mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-04 21:30:24 +08:00
feat: add casdoor as saml idp support (#571)
* feat: add casdoor as saml idp support Signed-off-by: 0x2a <stevesough@gmail.com> * fix: merge code Signed-off-by: 0x2a <stevesough@gmail.com> * fix: modify response value Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: modify samlResponse generation method Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: generating a response using etree Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: change metadata url Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: modify front-end adaptation Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: recovering an incorrect override Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: change the samlResponse location Signed-off-by: Steve0x2a <stevesough@gmail.com> * fix: add relayState support Signed-off-by: Steve0x2a <stevesough@gmail.com>
This commit is contained in:
@ -656,6 +656,7 @@ class App extends Component {
|
||||
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)}/>
|
||||
<Route exact path="/signup/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
|
||||
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
|
||||
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage account={this.state.account} type={"saml"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
|
||||
<Route exact path="/cas/:owner/:casApplicationName/logout" render={(props) => this.renderHomeIfLoggedIn(<CasLogout clearAccount={() => this.setState({account: null})} {...props} />)} />
|
||||
<Route exact path="/cas/:owner/:casApplicationName/login" render={(props) => {return (<LoginPage type={"cas"} mode={"signup"} account={this.state.account} {...props} />)}} />
|
||||
<Route exact path="/callback" component={AuthCallback}/>
|
||||
|
@ -135,7 +135,7 @@ class TokenEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.token.expiresIn} onChange={e => {
|
||||
this.updateTokenField('expiresIn', e.target.value);
|
||||
this.updateTokenField('expiresIn', parseInt(e.target.value));
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -49,6 +49,10 @@ class AuthCallback extends React.Component {
|
||||
const realRedirectUri = innerParams.get("redirect_uri");
|
||||
// Casdoor's own login page, so "code" is not necessary
|
||||
if (realRedirectUri === null) {
|
||||
const samlRequest = innerParams.get("SAMLRequest");
|
||||
if (samlRequest !== null && samlRequest !== undefined && samlRequest !== "") {
|
||||
return "saml"
|
||||
}
|
||||
return "login";
|
||||
}
|
||||
|
||||
@ -92,6 +96,7 @@ class AuthCallback extends React.Component {
|
||||
const applicationName = innerParams.get("application");
|
||||
const providerName = innerParams.get("provider");
|
||||
const method = innerParams.get("method");
|
||||
const samlRequest = innerParams.get("SAMLRequest");
|
||||
|
||||
let redirectUri = `${window.location.origin}/callback`;
|
||||
|
||||
@ -100,6 +105,7 @@ class AuthCallback extends React.Component {
|
||||
application: applicationName,
|
||||
provider: providerName,
|
||||
code: code,
|
||||
samlRequest: samlRequest,
|
||||
// state: innerParams.get("state"),
|
||||
state: applicationName,
|
||||
redirectUri: redirectUri,
|
||||
@ -127,6 +133,10 @@ class AuthCallback extends React.Component {
|
||||
} else if (responseType === "link") {
|
||||
const from = innerParams.get("from");
|
||||
Setting.goToLinkSoft(this, from);
|
||||
} else if (responseType === "saml") {
|
||||
const SAMLResponse = res.data;
|
||||
const redirectUri = res.data2;
|
||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
|
@ -53,6 +53,7 @@ class LoginPage extends React.Component {
|
||||
classes: props,
|
||||
type: props.type,
|
||||
applicationName: props.applicationName !== undefined ? props.applicationName : (props.match === undefined ? null : props.match.params.applicationName),
|
||||
owner : props.owner !== undefined ? props.owner : (props.match === undefined ? null : props.match.params.owner),
|
||||
application: null,
|
||||
mode: props.mode !== undefined ? props.mode : (props.match === undefined ? null : props.match.params.mode), // "signup" or "signin"
|
||||
isCodeSignin: false,
|
||||
@ -61,7 +62,6 @@ class LoginPage extends React.Component {
|
||||
validEmailOrPhone: false,
|
||||
validEmail: false,
|
||||
validPhone: false,
|
||||
owner: null,
|
||||
};
|
||||
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
||||
this.state.owner = props.match?.params.owner
|
||||
@ -74,6 +74,8 @@ class LoginPage extends React.Component {
|
||||
this.getApplication();
|
||||
} else if (this.state.type === "code") {
|
||||
this.getApplicationLogin();
|
||||
} else if (this.state.type === "saml"){
|
||||
this.getSamlApplication();
|
||||
} else {
|
||||
Util.showMessage("error", `Unknown authentication type: ${this.state.type}`);
|
||||
}
|
||||
@ -110,6 +112,19 @@ class LoginPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getSamlApplication(){
|
||||
if (this.state.applicationName === null){
|
||||
return;
|
||||
}
|
||||
ApplicationBackend.getApplication(this.state.owner, this.state.applicationName)
|
||||
.then((application) => {
|
||||
this.setState({
|
||||
application: application,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getApplicationObj() {
|
||||
if (this.props.application !== undefined) {
|
||||
return this.props.application;
|
||||
@ -157,7 +172,16 @@ class LoginPage extends React.Component {
|
||||
values["type"] = this.state.type;
|
||||
}
|
||||
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;
|
||||
|
||||
if (oAuthParams !== null){
|
||||
values["samlRequest"] = oAuthParams.samlRequest;
|
||||
}
|
||||
|
||||
|
||||
if (values["samlRequest"] != null && values["samlRequest"] !== "") {
|
||||
values["type"] = "saml";
|
||||
}
|
||||
|
||||
AuthBackend.login(values, oAuthParams)
|
||||
.then((res) => {
|
||||
if (res.status === 'ok') {
|
||||
@ -198,6 +222,10 @@ class LoginPage extends React.Component {
|
||||
} else if (responseType === "token" || responseType === "id_token") {
|
||||
const accessToken = res.data;
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
|
||||
} else if (responseType === "saml") {
|
||||
const SAMLResponse = res.data;
|
||||
const redirectUri = res.data2;
|
||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||
}
|
||||
} else {
|
||||
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||
|
@ -98,11 +98,13 @@ export function getOAuthGetParameters(params) {
|
||||
const redirectUri = getRefinedValue(queries.get("redirect_uri"));
|
||||
const scope = getRefinedValue(queries.get("scope"));
|
||||
const state = getRefinedValue(queries.get("state"));
|
||||
const nonce = getRefinedValue(queries.get("nonce"))
|
||||
const challengeMethod = getRefinedValue(queries.get("code_challenge_method"))
|
||||
const codeChallenge = getRefinedValue(queries.get("code_challenge"))
|
||||
|
||||
if (clientId === undefined || clientId === null || clientId === "") {
|
||||
const nonce = getRefinedValue(queries.get("nonce"));
|
||||
const challengeMethod = getRefinedValue(queries.get("code_challenge_method"));
|
||||
const codeChallenge = getRefinedValue(queries.get("code_challenge"));
|
||||
const samlRequest = getRefinedValue(queries.get("SAMLRequest"));
|
||||
const relayState = getRefinedValue(queries.get("RelayState"));
|
||||
|
||||
if ((clientId === undefined || clientId === null || clientId === "") && (samlRequest === "" || samlRequest === undefined)) {
|
||||
// login
|
||||
return null;
|
||||
} else {
|
||||
@ -116,6 +118,8 @@ export function getOAuthGetParameters(params) {
|
||||
nonce: nonce,
|
||||
challengeMethod: challengeMethod,
|
||||
codeChallenge: codeChallenge,
|
||||
samlRequest: samlRequest,
|
||||
relayState: relayState,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user