mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
Support Apple OAuth login now
This commit is contained in:
parent
140737b2f6
commit
9703f3f712
@ -488,7 +488,11 @@ func (c *ApiController) Login() {
|
|||||||
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||||
// OAuth
|
// OAuth
|
||||||
idpInfo := object.FromProviderToIdpInfo(c.Ctx, provider)
|
idpInfo := object.FromProviderToIdpInfo(c.Ctx, provider)
|
||||||
idProvider := idp.GetIdProvider(idpInfo, authForm.RedirectUri)
|
idProvider, err := idp.GetIdProvider(idpInfo, authForm.RedirectUri)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
if idProvider == nil {
|
if idProvider == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("storage:The provider type: %s is not supported"), provider.Type))
|
c.ResponseError(fmt.Sprintf(c.T("storage:The provider type: %s is not supported"), provider.Type))
|
||||||
return
|
return
|
||||||
|
24
idp/goth.go
24
idp/goth.go
@ -89,7 +89,7 @@ type GothIdProvider struct {
|
|||||||
Session goth.Session
|
Session goth.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGothIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string, hostUrl string) *GothIdProvider {
|
func NewGothIdProvider(providerType string, clientId string, clientSecret string, clientId2 string, clientSecret2 string, redirectUrl string, hostUrl string) (*GothIdProvider, error) {
|
||||||
var idp GothIdProvider
|
var idp GothIdProvider
|
||||||
switch providerType {
|
switch providerType {
|
||||||
case "Amazon":
|
case "Amazon":
|
||||||
@ -101,8 +101,24 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
|||||||
if !strings.Contains(redirectUrl, "/api/callback") {
|
if !strings.Contains(redirectUrl, "/api/callback") {
|
||||||
redirectUrl = strings.Replace(redirectUrl, "/callback", "/api/callback", 1)
|
redirectUrl = strings.Replace(redirectUrl, "/callback", "/api/callback", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iat := time.Now().Unix()
|
||||||
|
exp := iat + 60*60
|
||||||
|
sp := apple.SecretParams{
|
||||||
|
ClientId: clientId,
|
||||||
|
TeamId: clientSecret,
|
||||||
|
KeyId: clientId2,
|
||||||
|
PKCS8PrivateKey: clientSecret2,
|
||||||
|
Iat: int(iat),
|
||||||
|
Exp: int(exp),
|
||||||
|
}
|
||||||
|
secret, err := apple.MakeSecret(sp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
idp = GothIdProvider{
|
idp = GothIdProvider{
|
||||||
Provider: apple.New(clientId, clientSecret, redirectUrl, nil),
|
Provider: apple.New(clientId, *secret, redirectUrl, nil),
|
||||||
Session: &apple.Session{},
|
Session: &apple.Session{},
|
||||||
}
|
}
|
||||||
case "AzureAD":
|
case "AzureAD":
|
||||||
@ -386,10 +402,10 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
|||||||
Session: &zoom.Session{},
|
Session: &zoom.Session{},
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil, fmt.Errorf("OAuth Goth provider type: %s is not supported", providerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &idp
|
return &idp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHttpClient
|
// SetHttpClient
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package idp
|
package idp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -37,6 +38,8 @@ type ProviderInfo struct {
|
|||||||
SubType string
|
SubType string
|
||||||
ClientId string
|
ClientId string
|
||||||
ClientSecret string
|
ClientSecret string
|
||||||
|
ClientId2 string
|
||||||
|
ClientSecret2 string
|
||||||
AppId string
|
AppId string
|
||||||
HostUrl string
|
HostUrl string
|
||||||
RedirectUrl string
|
RedirectUrl string
|
||||||
@ -53,71 +56,71 @@ type IdProvider interface {
|
|||||||
GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) IdProvider {
|
func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) (IdProvider, error) {
|
||||||
switch idpInfo.Type {
|
switch idpInfo.Type {
|
||||||
case "GitHub":
|
case "GitHub":
|
||||||
return NewGithubIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewGithubIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Google":
|
case "Google":
|
||||||
return NewGoogleIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewGoogleIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "QQ":
|
case "QQ":
|
||||||
return NewQqIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewQqIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "WeChat":
|
case "WeChat":
|
||||||
return NewWeChatIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewWeChatIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Facebook":
|
case "Facebook":
|
||||||
return NewFacebookIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewFacebookIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "DingTalk":
|
case "DingTalk":
|
||||||
return NewDingTalkIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewDingTalkIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Weibo":
|
case "Weibo":
|
||||||
return NewWeiBoIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewWeiBoIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Gitee":
|
case "Gitee":
|
||||||
return NewGiteeIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewGiteeIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "LinkedIn":
|
case "LinkedIn":
|
||||||
return NewLinkedInIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewLinkedInIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "WeCom":
|
case "WeCom":
|
||||||
if idpInfo.SubType == "Internal" {
|
if idpInfo.SubType == "Internal" {
|
||||||
return NewWeComInternalIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewWeComInternalIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
} else if idpInfo.SubType == "Third-party" {
|
} else if idpInfo.SubType == "Third-party" {
|
||||||
return NewWeComIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewWeComIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil, fmt.Errorf("WeCom provider subType: %s is not supported", idpInfo.SubType)
|
||||||
}
|
}
|
||||||
case "Lark":
|
case "Lark":
|
||||||
return NewLarkIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewLarkIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "GitLab":
|
case "GitLab":
|
||||||
return NewGitlabIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewGitlabIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "ADFS":
|
case "ADFS":
|
||||||
return NewAdfsIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
return NewAdfsIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl), nil
|
||||||
case "Baidu":
|
case "Baidu":
|
||||||
return NewBaiduIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewBaiduIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Alipay":
|
case "Alipay":
|
||||||
return NewAlipayIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewAlipayIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Custom":
|
case "Custom":
|
||||||
return NewCustomIdProvider(idpInfo, redirectUrl)
|
return NewCustomIdProvider(idpInfo, redirectUrl), nil
|
||||||
case "Infoflow":
|
case "Infoflow":
|
||||||
if idpInfo.SubType == "Internal" {
|
if idpInfo.SubType == "Internal" {
|
||||||
return NewInfoflowInternalIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, idpInfo.AppId, redirectUrl)
|
return NewInfoflowInternalIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, idpInfo.AppId, redirectUrl), nil
|
||||||
} else if idpInfo.SubType == "Third-party" {
|
} else if idpInfo.SubType == "Third-party" {
|
||||||
return NewInfoflowIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, idpInfo.AppId, redirectUrl)
|
return NewInfoflowIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, idpInfo.AppId, redirectUrl), nil
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil, fmt.Errorf("Infoflow provider subType: %s is not supported", idpInfo.SubType)
|
||||||
}
|
}
|
||||||
case "Casdoor":
|
case "Casdoor":
|
||||||
return NewCasdoorIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
return NewCasdoorIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl), nil
|
||||||
case "Okta":
|
case "Okta":
|
||||||
return NewOktaIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
return NewOktaIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl), nil
|
||||||
case "Douyin":
|
case "Douyin":
|
||||||
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Bilibili":
|
case "Bilibili":
|
||||||
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "MetaMask":
|
case "MetaMask":
|
||||||
return NewMetaMaskIdProvider()
|
return NewMetaMaskIdProvider(), nil
|
||||||
case "Web3Onboard":
|
case "Web3Onboard":
|
||||||
return NewWeb3OnboardIdProvider()
|
return NewWeb3OnboardIdProvider(), nil
|
||||||
default:
|
default:
|
||||||
if isGothSupport(idpInfo.Type) {
|
if isGothSupport(idpInfo.Type) {
|
||||||
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, idpInfo.ClientId2, idpInfo.ClientSecret2, redirectUrl, idpInfo.HostUrl)
|
||||||
}
|
}
|
||||||
return nil
|
return nil, fmt.Errorf("OAuth provider type: %s is not supported", idpInfo.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ type Provider struct {
|
|||||||
ClientId string `xorm:"varchar(200)" json:"clientId"`
|
ClientId string `xorm:"varchar(200)" json:"clientId"`
|
||||||
ClientSecret string `xorm:"varchar(2000)" json:"clientSecret"`
|
ClientSecret string `xorm:"varchar(2000)" json:"clientSecret"`
|
||||||
ClientId2 string `xorm:"varchar(100)" json:"clientId2"`
|
ClientId2 string `xorm:"varchar(100)" json:"clientId2"`
|
||||||
ClientSecret2 string `xorm:"varchar(100)" json:"clientSecret2"`
|
ClientSecret2 string `xorm:"varchar(500)" json:"clientSecret2"`
|
||||||
Cert string `xorm:"varchar(100)" json:"cert"`
|
Cert string `xorm:"varchar(100)" json:"cert"`
|
||||||
CustomAuthUrl string `xorm:"varchar(200)" json:"customAuthUrl"`
|
CustomAuthUrl string `xorm:"varchar(200)" json:"customAuthUrl"`
|
||||||
CustomTokenUrl string `xorm:"varchar(200)" json:"customTokenUrl"`
|
CustomTokenUrl string `xorm:"varchar(200)" json:"customTokenUrl"`
|
||||||
@ -402,6 +402,8 @@ func FromProviderToIdpInfo(ctx *context.Context, provider *Provider) *idp.Provid
|
|||||||
SubType: provider.SubType,
|
SubType: provider.SubType,
|
||||||
ClientId: provider.ClientId,
|
ClientId: provider.ClientId,
|
||||||
ClientSecret: provider.ClientSecret,
|
ClientSecret: provider.ClientSecret,
|
||||||
|
ClientId2: provider.ClientId2,
|
||||||
|
ClientSecret2: provider.ClientSecret2,
|
||||||
AppId: provider.AppId,
|
AppId: provider.AppId,
|
||||||
HostUrl: provider.Host,
|
HostUrl: provider.Host,
|
||||||
TokenURL: provider.CustomTokenUrl,
|
TokenURL: provider.CustomTokenUrl,
|
||||||
|
@ -152,6 +152,12 @@ class ProviderEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
getClientIdLabel(provider) {
|
getClientIdLabel(provider) {
|
||||||
switch (provider.category) {
|
switch (provider.category) {
|
||||||
|
case "OAuth":
|
||||||
|
if (provider.type === "Apple") {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Service ID identifier"), i18next.t("provider:Service ID identifier - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
||||||
|
}
|
||||||
case "Email":
|
case "Email":
|
||||||
return Setting.getLabel(i18next.t("signup:Username"), i18next.t("signup:Username - Tooltip"));
|
return Setting.getLabel(i18next.t("signup:Username"), i18next.t("signup:Username - Tooltip"));
|
||||||
case "SMS":
|
case "SMS":
|
||||||
@ -185,6 +191,12 @@ class ProviderEditPage extends React.Component {
|
|||||||
|
|
||||||
getClientSecretLabel(provider) {
|
getClientSecretLabel(provider) {
|
||||||
switch (provider.category) {
|
switch (provider.category) {
|
||||||
|
case "OAuth":
|
||||||
|
if (provider.type === "Apple") {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Team ID"), i18next.t("provider:Team ID - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||||
|
}
|
||||||
case "Email":
|
case "Email":
|
||||||
if (provider.type === "Azure ACS") {
|
if (provider.type === "Azure ACS") {
|
||||||
return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
|
||||||
@ -226,6 +238,12 @@ class ProviderEditPage extends React.Component {
|
|||||||
|
|
||||||
getClientId2Label(provider) {
|
getClientId2Label(provider) {
|
||||||
switch (provider.category) {
|
switch (provider.category) {
|
||||||
|
case "OAuth":
|
||||||
|
if (provider.type === "Apple") {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Key ID"), i18next.t("provider:Key ID - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client ID 2"), i18next.t("provider:Client ID 2 - Tooltip"));
|
||||||
|
}
|
||||||
case "Email":
|
case "Email":
|
||||||
return Setting.getLabel(i18next.t("provider:From address"), i18next.t("provider:From address - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:From address"), i18next.t("provider:From address - Tooltip"));
|
||||||
default:
|
default:
|
||||||
@ -241,6 +259,12 @@ class ProviderEditPage extends React.Component {
|
|||||||
|
|
||||||
getClientSecret2Label(provider) {
|
getClientSecret2Label(provider) {
|
||||||
switch (provider.category) {
|
switch (provider.category) {
|
||||||
|
case "OAuth":
|
||||||
|
if (provider.type === "Apple") {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Key text"), i18next.t("provider:Key text - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client secret 2"), i18next.t("provider:Client secret 2 - Tooltip"));
|
||||||
|
}
|
||||||
case "Email":
|
case "Email":
|
||||||
return Setting.getLabel(i18next.t("provider:From name"), i18next.t("provider:From name - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:From name"), i18next.t("provider:From name - Tooltip"));
|
||||||
default:
|
default:
|
||||||
@ -675,7 +699,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.provider.category !== "Email" && this.state.provider.type !== "WeChat" && this.state.provider.type !== "Aliyun Captcha" && this.state.provider.type !== "WeChat Pay" && this.state.provider.type !== "Twitter" && this.state.provider.type !== "Reddit" ? null : (
|
this.state.provider.category !== "Email" && this.state.provider.type !== "WeChat" && this.state.provider.type !== "Apple" && this.state.provider.type !== "Aliyun Captcha" && this.state.provider.type !== "WeChat Pay" && this.state.provider.type !== "Twitter" && this.state.provider.type !== "Reddit" ? null : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user