feat: fix CAS login bug (#2230)

* fix: cas login

* fix: cas login

* feat: rollback get-default-app change

* fix : move cas restrict logic to GetApplicationLogin()

* fix: format code

* fix: fix getOAuthGetParameters for cas

* fix: fix getOAuthGetParameters for cas

* fix: cas login
This commit is contained in:
haiwu 2023-08-19 01:05:55 +08:00 committed by Yang Luo
parent a2db61cc1a
commit fec54944dd
5 changed files with 67 additions and 13 deletions

View File

@ -187,11 +187,34 @@ func (c *ApiController) GetApplicationLogin() {
redirectUri := c.Input().Get("redirectUri") redirectUri := c.Input().Get("redirectUri")
scope := c.Input().Get("scope") scope := c.Input().Get("scope")
state := c.Input().Get("state") state := c.Input().Get("state")
id := c.Input().Get("id")
loginType := c.Input().Get("type")
msg, application, err := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage()) var application *object.Application
if err != nil { var msg string
c.ResponseError(err.Error()) var err error
return if loginType == "code" {
msg, application, err = object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
if err != nil {
c.ResponseError(err.Error())
return
}
} else if loginType == "cas" {
application, err = object.GetApplication(id)
if err != nil {
c.ResponseError(err.Error())
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), id))
return
}
err = object.CheckCasLogin(application, c.GetAcceptLanguage(), redirectUri)
if err != nil {
c.ResponseError(err.Error())
return
}
} }
application = object.GetMaskedApplication(application, "") application = object.GetMaskedApplication(application, "")

View File

@ -26,6 +26,7 @@ import (
"time" "time"
"github.com/beevik/etree" "github.com/beevik/etree"
"github.com/casdoor/casdoor/i18n"
"github.com/casdoor/casdoor/util" "github.com/casdoor/casdoor/util"
dsig "github.com/russellhaering/goxmldsig" dsig "github.com/russellhaering/goxmldsig"
) )
@ -122,6 +123,13 @@ var stToServiceResponse sync.Map
// pgt is short for proxy granting ticket // pgt is short for proxy granting ticket
var pgtToServiceResponse sync.Map var pgtToServiceResponse sync.Map
func CheckCasLogin(application *Application, lang string, service string) error {
if len(application.RedirectUris) > 0 && !application.IsRedirectUriValid(service) {
return fmt.Errorf(i18n.Translate(lang, "token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), service)
}
return nil
}
func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string { func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string {
pgt := fmt.Sprintf("PGT-%s", util.GenerateId()) pgt := fmt.Sprintf("PGT-%s", util.GenerateId())
pgtToServiceResponse.Store(pgt, &CasAuthenticationSuccessWrapper{ pgtToServiceResponse.Store(pgt, &CasAuthenticationSuccessWrapper{

View File

@ -46,6 +46,10 @@ export function getEmailAndPhone(organization, username) {
}).then((res) => res.json()); }).then((res) => res.json());
} }
export function casLoginParamsToQuery(casParams) {
return `?type=${casParams?.type}&id=${casParams?.id}&redirectUri=${casParams?.service}`;
}
export function oAuthParamsToQuery(oAuthParams) { export function oAuthParamsToQuery(oAuthParams) {
// login // login
if (oAuthParams === null || oAuthParams === undefined) { if (oAuthParams === null || oAuthParams === undefined) {
@ -53,11 +57,12 @@ export function oAuthParamsToQuery(oAuthParams) {
} }
// code // code
return `?clientId=${oAuthParams.clientId}&responseType=${oAuthParams.responseType}&redirectUri=${encodeURIComponent(oAuthParams.redirectUri)}&scope=${oAuthParams.scope}&state=${oAuthParams.state}&nonce=${oAuthParams.nonce}&code_challenge_method=${oAuthParams.challengeMethod}&code_challenge=${oAuthParams.codeChallenge}`; return `?clientId=${oAuthParams.clientId}&responseType=${oAuthParams.responseType}&redirectUri=${encodeURIComponent(oAuthParams.redirectUri)}&type=${oAuthParams.type}&scope=${oAuthParams.scope}&state=${oAuthParams.state}&nonce=${oAuthParams.nonce}&code_challenge_method=${oAuthParams.challengeMethod}&code_challenge=${oAuthParams.codeChallenge}`;
} }
export function getApplicationLogin(oAuthParams) { export function getApplicationLogin(params) {
return fetch(`${authConfig.serverUrl}/api/get-app-login${oAuthParamsToQuery(oAuthParams)}`, { const queryParams = (params?.type === "cas") ? casLoginParamsToQuery(params) : oAuthParamsToQuery(params);
return fetch(`${authConfig.serverUrl}/api/get-app-login${queryParams}`, {
method: "GET", method: "GET",
credentials: "include", credentials: "include",
headers: { headers: {

View File

@ -71,9 +71,9 @@ class LoginPage extends React.Component {
componentDidMount() { componentDidMount() {
if (this.getApplicationObj() === undefined) { if (this.getApplicationObj() === undefined) {
if (this.state.type === "login" || this.state.type === "cas" || this.state.type === "saml") { if (this.state.type === "login" || this.state.type === "saml") {
this.getApplication(); this.getApplication();
} else if (this.state.type === "code") { } else if (this.state.type === "code" || this.state.type === "cas") {
this.getApplicationLogin(); this.getApplicationLogin();
} else { } else {
Setting.showMessage("error", `Unknown authentication type: ${this.state.type}`); Setting.showMessage("error", `Unknown authentication type: ${this.state.type}`);
@ -143,8 +143,8 @@ class LoginPage extends React.Component {
} }
getApplicationLogin() { getApplicationLogin() {
const oAuthParams = Util.getOAuthGetParameters(); const loginParams = (this.state.type === "cas") ? Util.getCasLoginParameters("admin", this.state.applicationName) : Util.getOAuthGetParameters();
AuthBackend.getApplicationLogin(oAuthParams) AuthBackend.getApplicationLogin(loginParams)
.then((res) => { .then((res) => {
if (res.status === "ok") { if (res.status === "ok") {
const application = res.data; const application = res.data;
@ -167,8 +167,11 @@ class LoginPage extends React.Component {
ApplicationBackend.getApplication("admin", this.state.applicationName) ApplicationBackend.getApplication("admin", this.state.applicationName)
.then((res) => { .then((res) => {
if (res.status === "error") { if (res.status === "error") {
Setting.showMessage("error", res.msg); this.onUpdateApplication(null);
return; this.setState({
msg: res.msg,
});
return ;
} }
this.onUpdateApplication(res.data); this.onUpdateApplication(res.data);
}); });

View File

@ -96,6 +96,20 @@ function getRawGetParameter(key) {
return res; return res;
} }
export function getCasLoginParameters(owner, name) {
const queries = new URLSearchParams(window.location.search);
// CAS service
let service = getRawGetParameter("service");
if (service === "") {
service = getRefinedValue(queries.get("service"));
}
return {
id: `${owner}/${encodeURIComponent(name)}`, // application ID,
service: service,
type: "cas",
};
}
export function getOAuthGetParameters(params) { export function getOAuthGetParameters(params) {
const queries = (params !== undefined) ? params : new URLSearchParams(window.location.search); const queries = (params !== undefined) ? params : new URLSearchParams(window.location.search);
const clientId = getRefinedValue(queries.get("client_id")); const clientId = getRefinedValue(queries.get("client_id"));
@ -144,6 +158,7 @@ export function getOAuthGetParameters(params) {
samlRequest: samlRequest, samlRequest: samlRequest,
relayState: relayState, relayState: relayState,
noRedirect: noRedirect, noRedirect: noRedirect,
type: "code",
}; };
} }
} }