casdoor/web/src/auth/AuthCallback.js

211 lines
7.5 KiB
JavaScript
Raw Normal View History

2022-02-13 23:39:27 +08:00
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
2021-02-14 00:22:24 +08:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
2021-03-15 00:49:16 +08:00
import {Spin} from "antd";
2021-02-14 00:22:24 +08:00
import {withRouter} from "react-router-dom";
2021-02-14 15:40:57 +08:00
import * as AuthBackend from "./AuthBackend";
2021-03-15 00:49:16 +08:00
import * as Util from "./Util";
2021-03-21 00:38:00 +08:00
import {authConfig} from "./Auth";
2021-03-26 21:58:19 +08:00
import * as Setting from "../Setting";
import i18next from "i18next";
import RedirectForm from "../common/RedirectForm";
2021-02-14 00:22:24 +08:00
2021-02-14 00:54:42 +08:00
class AuthCallback extends React.Component {
2021-02-14 00:22:24 +08:00
constructor(props) {
super(props);
this.state = {
classes: props,
2021-03-25 23:22:34 +08:00
msg: null,
samlResponse: "",
relayState: "",
redirectUrl: "",
2021-02-14 00:22:24 +08:00
};
}
2021-03-21 13:45:55 +08:00
getInnerParams() {
// For example, for Casbin-OA, realRedirectUri = "http://localhost:9000/login"
// realRedirectUrl = "http://localhost:9000"
const params = new URLSearchParams(this.props.location.search);
const state = params.get("state");
const queryString = Util.getQueryParamsFromState(state);
2021-04-19 01:14:41 +08:00
return new URLSearchParams(queryString);
2021-03-21 13:45:55 +08:00
}
2021-03-21 00:38:00 +08:00
getResponseType() {
// "http://localhost:8000"
const authServerUrl = authConfig.serverUrl;
2021-03-21 13:45:55 +08:00
const innerParams = this.getInnerParams();
2021-04-19 01:14:41 +08:00
const method = innerParams.get("method");
if (method === "signup") {
const realRedirectUri = innerParams.get("redirect_uri");
// Casdoor's own login page, so "code" is not necessary
if (realRedirectUri === null) {
const samlRequest = innerParams.get("SAMLRequest");
// cas don't use 'redirect_url', it is called 'service'
const casService = innerParams.get("service");
if (samlRequest !== null && samlRequest !== undefined && samlRequest !== "") {
return "saml";
} else if (casService !== null && casService !== undefined && casService !== "") {
return "cas";
}
return "login";
}
2021-04-19 01:14:41 +08:00
const realRedirectUrl = new URL(realRedirectUri).origin;
2021-03-21 00:38:00 +08:00
2021-04-19 01:14:41 +08:00
// For Casdoor itself, we use "login" directly
if (authServerUrl === realRedirectUrl) {
return "login";
} else {
const responseType = innerParams.get("response_type");
if (responseType !== null) {
return responseType;
}
2021-04-19 01:14:41 +08:00
return "code";
}
} else if (method === "link") {
return "link";
2021-03-21 00:38:00 +08:00
} else {
2021-04-19 01:14:41 +08:00
return "unknown";
2021-03-21 00:38:00 +08:00
}
}
2021-03-27 11:38:15 +08:00
UNSAFE_componentWillMount() {
2021-03-20 22:34:22 +08:00
const params = new URLSearchParams(this.props.location.search);
const isSteam = params.get("openid.mode");
2021-08-01 11:20:06 +08:00
let code = params.get("code");
// WeCom returns "auth_code=xxx" instead of "code=xxx"
if (code === null) {
code = params.get("auth_code");
}
// Dingtalk now returns "authCode=xxx" instead of "code=xxx"
if (code === null) {
code = params.get("authCode");
}
// Steam don't use code, so we should use all params as code.
if (isSteam !== null && code === null) {
code = this.props.location.search;
}
2021-05-30 15:13:43 +08:00
2021-03-21 13:45:55 +08:00
const innerParams = this.getInnerParams();
2021-03-21 16:05:00 +08:00
const applicationName = innerParams.get("application");
const providerName = innerParams.get("provider");
const method = innerParams.get("method");
const samlRequest = innerParams.get("SAMLRequest");
const casService = innerParams.get("service");
2021-05-30 15:13:43 +08:00
const redirectUri = `${window.location.origin}/callback`;
2021-05-30 15:13:43 +08:00
2021-03-15 00:49:16 +08:00
const body = {
2021-03-21 00:38:00 +08:00
type: this.getResponseType(),
2021-03-21 16:05:00 +08:00
application: applicationName,
provider: providerName,
2021-05-30 15:13:43 +08:00
code: code,
samlRequest: samlRequest,
2021-04-19 01:14:41 +08:00
// state: innerParams.get("state"),
2021-05-30 15:13:43 +08:00
state: applicationName,
2021-03-15 00:49:16 +08:00
redirectUri: redirectUri,
2021-03-21 16:05:00 +08:00
method: method,
2021-03-15 00:49:16 +08:00
};
if (this.getResponseType() === "cas") {
// user is using casdoor as cas sso server, and wants the ticket to be acquired
AuthBackend.loginCas(body, {"service": casService}).then((res) => {
if (res.status === "ok") {
let msg = "Logged in successfully.";
if (casService === "") {
// If service was not specified, Casdoor must display a message notifying the client that it has successfully initiated a single sign-on session.
msg += "Now you can visit apps protected by Casdoor.";
}
Setting.showMessage("success", msg);
if (casService !== "") {
const st = res.data;
const newUrl = new URL(casService);
newUrl.searchParams.append("ticket", st);
window.location.href = newUrl.toString();
}
} else {
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
}
});
return;
}
// OAuth
2021-03-21 13:45:55 +08:00
const oAuthParams = Util.getOAuthGetParameters(innerParams);
const concatChar = oAuthParams?.redirectUri?.includes("?") ? "&" : "?";
2021-03-20 16:51:10 +08:00
AuthBackend.login(body, oAuthParams)
2021-02-14 00:54:42 +08:00
.then((res) => {
if (res.status === "ok") {
2021-03-21 00:38:00 +08:00
const responseType = this.getResponseType();
if (responseType === "login") {
Setting.showMessage("success", "Logged in successfully");
// Setting.goToLinkSoft(this, "/");
2022-02-12 09:55:06 +08:00
const link = Setting.getFromLink();
Setting.goToLink(link);
2021-03-21 00:38:00 +08:00
} else if (responseType === "code") {
const code = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
// Setting.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
const token = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
2021-04-19 01:14:41 +08:00
} else if (responseType === "link") {
const from = innerParams.get("from");
Setting.goToLinkSoft(this, from);
} else if (responseType === "saml") {
if (res.data2.method === "POST") {
this.setState({
samlResponse: res.data,
redirectUrl: res.data2.redirectUrl,
relayState: oAuthParams.relayState,
});
} else {
const SAMLResponse = res.data;
const redirectUri = res.data2.redirectUrl;
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
}
2021-03-21 00:38:00 +08:00
}
2021-02-14 14:34:03 +08:00
} else {
2021-03-26 21:58:19 +08:00
this.setState({
msg: res.msg,
});
2021-02-14 00:54:42 +08:00
}
});
2021-02-14 00:22:24 +08:00
}
render() {
if (this.state.samlResponse !== "") {
return <RedirectForm samlResponse={this.state.samlResponse} redirectUrl={this.state.redirectUrl} relayState={this.state.relayState} />;
}
2021-02-14 00:22:24 +08:00
return (
<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}>
2021-03-25 23:22:34 +08:00
{
(this.state.msg === null) ? (
<Spin size="large" tip={i18next.t("login:Signing in...")} style={{paddingTop: "10%"}} />
2021-03-25 23:22:34 +08:00
) : (
2021-03-26 21:58:19 +08:00
Util.renderMessageLarge(this, this.state.msg)
2021-03-25 23:22:34 +08:00
)
}
2021-02-14 00:22:24 +08:00
</div>
);
2021-02-14 00:22:24 +08:00
}
}
2021-02-14 00:54:42 +08:00
export default withRouter(AuthCallback);