Skip to content

Commit

Permalink
feat: add implicit flow support (casdoor#520)
Browse files Browse the repository at this point in the history
* feat: add implicit flow support

Signed-off-by: Steve0x2a <[email protected]>

* fix: idp support in implicit flow

Signed-off-by: Steve0x2a <[email protected]>
  • Loading branch information
Steve0x2a authored Mar 1, 2022
1 parent d48d515 commit 697b3e4
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 10 deletions.
6 changes: 4 additions & 2 deletions controllers/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import (
)

const (
ResponseTypeLogin = "login"
ResponseTypeCode = "code"
ResponseTypeLogin = "login"
ResponseTypeCode = "code"
ResponseTypeToken = "token"
ResponseTypeIdToken = "id_token"
)

type RequestForm struct {
Expand Down
17 changes: 17 additions & 0 deletions controllers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ func codeToResponse(code *object.Code) *Response {
return &Response{Status: "ok", Msg: "", Data: code.Code}
}

func tokenToResponse(token *object.Token) *Response {
if token.AccessToken == "" {
return &Response{Status: "error", Msg: "fail to get accessToken", Data: token.AccessToken}
}
return &Response{Status: "ok", Msg: "", Data: token.AccessToken}

}

// HandleLoggedIn ...
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) (resp *Response) {
userId := user.GetId()
Expand Down Expand Up @@ -66,6 +74,15 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
// The prompt page needs the user to be signed in
c.SetSessionUsername(userId)
}
} else if form.Type == ResponseTypeToken || form.Type == ResponseTypeIdToken { //implicit flow
if !object.IsGrantTypeValid(form.Type, application.GrantTypes) {
resp = &Response{Status: "error", Msg: fmt.Sprintf("error: grant_type: %s is not supported in this application", form.Type), Data: ""}
} else {
scope := c.Input().Get("scope")
token, _ := object.GetTokenByUser(application, user, scope, c.Ctx.Request.Host)
resp = tokenToResponse(token)
}

} else {
resp = &Response{Status: "error", Msg: fmt.Sprintf("Unknown response type: %s", form.Type)}
}
Expand Down
33 changes: 29 additions & 4 deletions object/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ func GetTokenByAccessToken(accessToken string) *Token {
}

func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string) (string, *Application) {
if responseType != "code" {
return "response_type should be \"code\"", nil
if responseType != "code" && responseType != "token" && responseType != "id_token" {
return fmt.Sprintf("error: grant_type: %s is not supported in this application", responseType), nil
}

application := GetApplicationByClientId(clientId)
Expand Down Expand Up @@ -274,7 +274,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
}

//Check if grantType is allowed in the current application
if !isGrantTypeValid(grantType, application.GrantTypes) {
if !IsGrantTypeValid(grantType, application.GrantTypes) {
return &TokenWrapper{
AccessToken: fmt.Sprintf("error: grant_type: %s is not supported in this application", grantType),
TokenType: "",
Expand Down Expand Up @@ -418,7 +418,7 @@ func pkceChallenge(verifier string) string {

// Check if grantType is allowed in the current application
// authorization_code is allowed by default
func isGrantTypeValid(method string, grantTypes []string) bool {
func IsGrantTypeValid(method string, grantTypes []string) bool {
if method == "authorization_code" {
return true
}
Expand Down Expand Up @@ -527,3 +527,28 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
AddToken(token)
return token, nil
}

// Implicit flow
func GetTokenByUser(application *Application, user *User, scope string, host string) (*Token, error) {
accessToken, refreshToken, err := generateJwtToken(application, user, "", scope, host)
if err != nil {
return nil, err
}
token := &Token{
Owner: application.Owner,
Name: util.GenerateId(),
CreatedTime: util.GetCurrentTime(),
Application: application.Name,
Organization: user.Owner,
User: user.Name,
Code: util.GenerateClientId(),
AccessToken: accessToken,
RefreshToken: refreshToken,
ExpiresIn: application.ExpireInHours * 60,
Scope: scope,
TokenType: "Bearer",
CodeIsUsed: true,
}
AddToken(token)
return token, nil
}
2 changes: 2 additions & 0 deletions web/src/ApplicationEditPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ class ApplicationEditPage extends React.Component {
{id: "authorization_code", name: "Authorization Code"},
{id: "password", name: "Password"},
{id: "client_credentials", name: "Client Credentials"},
{id: "token", name: "Token"},
{id: "id_token",name:"ID Token"},
].map((item, index)=><Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
Expand Down
7 changes: 7 additions & 0 deletions web/src/auth/AuthCallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class AuthCallback extends React.Component {
if (authServerUrl === realRedirectUrl) {
return "login";
} else {
const responseType = innerParams.get("response_type");
if (responseType !== null) {
return responseType
}
return "code";
}
} else if (method === "link") {
Expand Down Expand Up @@ -116,6 +120,9 @@ class AuthCallback extends React.Component {
const code = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
// Util.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token"){
const token = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}?${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
} else if (responseType === "link") {
const from = innerParams.get("from");
Setting.goToLinkSoft(this, from);
Expand Down
15 changes: 11 additions & 4 deletions web/src/auth/LoginPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,18 @@ class LoginPage extends React.Component {
onFinish(values) {
const application = this.getApplicationObj();
const ths = this;
values["type"] = this.state.type;
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;
const oAuthParams = Util.getOAuthGetParameters();

if (oAuthParams !== null && oAuthParams.responseType!= null && oAuthParams.responseType !== "") {
values["type"] = oAuthParams.responseType
}else{
values["type"] = this.state.type;
}
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;

AuthBackend.login(values, oAuthParams)
.then((res) => {
if (res.status === 'ok') {
const responseType = this.state.type;
const responseType = values["type"];
if (responseType === "login") {
Util.showMessage("success", `Logged in successfully`);

Expand Down Expand Up @@ -156,6 +160,9 @@ class LoginPage extends React.Component {
}

// Util.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
const accessToken = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
}
} else {
Util.showMessage("error", `Failed to log in: ${res.msg}`);
Expand Down

0 comments on commit 697b3e4

Please sign in to comment.