mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-07 01:18:27 +08:00
/authz/oauth/v20
This commit is contained in:
parent
0325f76e19
commit
173f779267
@ -207,8 +207,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
|
||||
#############################################################################
|
||||
# OIDC V1.0 METADATA configuration
|
||||
maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token
|
||||
maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo
|
||||
|
||||
#############################################################################
|
||||
|
||||
@ -64,7 +64,7 @@ public class AuthorizeEndpoint extends AuthorizeBaseEndpoint{
|
||||
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.FORMBASED)){
|
||||
modelAndView=WebContext.forward("/authz/formbased/"+id);
|
||||
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.OAUTH20)){
|
||||
modelAndView=WebContext.forward("/authz/oauthv20/"+application.getId());
|
||||
modelAndView=WebContext.forward("/authz/oauth/v20/"+application.getId());
|
||||
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.OPEN_ID_CONNECT)){
|
||||
// modelAndView=new ModelAndView("openid connect");
|
||||
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.SAML20)){
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
package org.maxkey.authz.oauth2.common;
|
||||
|
||||
public class OAuth2Constants {
|
||||
|
||||
public static final class PARAMETER{
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String CLIENT_ID = "client_id";
|
||||
|
||||
public static final String CLIENT_SECRET = "client_secret";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String STATE = "state";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String SCOPE = "scope";
|
||||
|
||||
public static final String CODE = "code";
|
||||
|
||||
public static final String EXPIRES_IN = "expires_in";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String REDIRECT_URI = "redirect_uri";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String RESPONSE_TYPE = "response_type";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String USER_OAUTH_APPROVAL = "user_oauth_approval";
|
||||
|
||||
/**
|
||||
* Constant to use as a prefix for scope approval
|
||||
*/
|
||||
public static final String SCOPE_PREFIX = "scope.";
|
||||
|
||||
/**
|
||||
* Constant to use while parsing and formatting parameter maps for OAuth2 requests
|
||||
*/
|
||||
public static final String GRANT_TYPE = "grant_type";
|
||||
|
||||
public static final String ACCESS_TOKEN = "access_token";
|
||||
}
|
||||
|
||||
public static class ENDPOINT{
|
||||
|
||||
public final static String ENDPOINT_BASE = "/authz/oauth/v20";
|
||||
|
||||
public final static String ENDPOINT_AUTHORIZE = ENDPOINT_BASE + "/authorize";
|
||||
|
||||
public final static String ENDPOINT_TOKEN = ENDPOINT_BASE + "/token";
|
||||
|
||||
public final static String ENDPOINT_CHECK_TOKEN = ENDPOINT_BASE + "/check_token";
|
||||
|
||||
public final static String ENDPOINT_TOKEN_KEY = ENDPOINT_BASE + "/token_key";
|
||||
|
||||
public final static String ENDPOINT_APPROVAL_CONFIRM = ENDPOINT_BASE + "/approval_confirm";
|
||||
|
||||
public final static String ENDPOINT_ERROR = ENDPOINT_BASE + "/error";
|
||||
|
||||
public final static String ENDPOINT_USERINFO = "/api/oauth/v20/me";
|
||||
|
||||
public final static String ENDPOINT_OPENID_CONNECT_USERINFO = "/api/connect/v10/userinfo";
|
||||
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.util.OAuth2Utils;
|
||||
import org.maxkey.authz.oauth2.provider.AuthorizationRequest;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
@ -73,7 +74,7 @@ public class OAuth20AccessConfirmationController {
|
||||
* @return
|
||||
* throws Exception
|
||||
*/
|
||||
@RequestMapping("/oauth/v20/approval_confirm")
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM)
|
||||
public ModelAndView getAccessConfirmation(
|
||||
@RequestParam Map<String, Object> model) throws Exception {
|
||||
model.remove("authorizationRequest");
|
||||
@ -123,7 +124,7 @@ public class OAuth20AccessConfirmationController {
|
||||
* @return
|
||||
* throws Exception
|
||||
*/
|
||||
@RequestMapping("/oauth/v20/error")
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_ERROR)
|
||||
public String handleError(Map<String, Object> model) throws Exception {
|
||||
// We can add more stuff to the model here for JSP rendering. If the client was
|
||||
// a machine then
|
||||
|
||||
@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||
@ -99,7 +100,7 @@ import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
final static Logger _logger = LoggerFactory.getLogger(AuthorizationEndpoint.class);
|
||||
|
||||
private static final String OAUTH_V20_AUTHORIZATION_URL = "%s/oauth/v20/authorize?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto";
|
||||
private static final String OAUTH_V20_AUTHORIZATION_URL = "%s" + OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE + "?client_id=%s&response_type=code&redirect_uri=%s&approval_prompt=auto";
|
||||
|
||||
@Autowired
|
||||
@Qualifier("oauth20JdbcClientDetailsService")
|
||||
@ -117,9 +118,9 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
|
||||
private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator();
|
||||
|
||||
private String userApprovalPage = "forward:/oauth/v20/approval_confirm";
|
||||
private String userApprovalPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM;
|
||||
|
||||
private String errorPage = "forward:/oauth/error";
|
||||
private String errorPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_ERROR;
|
||||
|
||||
private Object implicitLock = new Object();
|
||||
|
||||
@ -132,7 +133,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "OAuth 2.0 认证接口", notes = "传递参数client_id,response_type,redirect_uri等",httpMethod="GET")
|
||||
@RequestMapping(value = "/oauth/v20/authorize", method = RequestMethod.GET)
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE, method = RequestMethod.GET)
|
||||
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
|
||||
SessionStatus sessionStatus) {
|
||||
Principal principal=(Principal)WebContext.getAuthentication();
|
||||
@ -211,7 +212,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/oauth/v20/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE, method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
|
||||
public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, ?> model,
|
||||
SessionStatus sessionStatus) {
|
||||
Principal principal=(Principal)WebContext.getAuthentication();
|
||||
@ -514,7 +515,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "OAuth 2.0 认证接口", notes = "传递参数应用ID,自动完成跳转认证拼接",httpMethod="GET")
|
||||
@RequestMapping("/authz/oauthv20/{id}")
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{id}")
|
||||
public ModelAndView authorize(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
|
||||
@ -34,6 +34,7 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidTokenException;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
@ -81,7 +82,7 @@ public class CheckTokenEndpoint {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "OAuth 2.0 token检查接口", notes = "传递参数token",httpMethod="POST")
|
||||
@RequestMapping(value = "/oauth/v20/check_token")
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_CHECK_TOKEN)
|
||||
@ResponseBody
|
||||
public Map<String, ?> checkToken(@RequestParam("token") String value) {
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Set;
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException;
|
||||
@ -89,7 +90,7 @@ public class TokenEndpoint extends AbstractEndpoint {
|
||||
* @throws HttpRequestMethodNotSupportedException
|
||||
*/
|
||||
@ApiOperation(value = "OAuth 2.0 获取AccessToken接口", notes = "传递参数token等",httpMethod="GET")
|
||||
@RequestMapping(value = "/oauth/v20/token", method=RequestMethod.GET)
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN, method=RequestMethod.GET)
|
||||
public ResponseEntity<OAuth2AccessToken> getAccessToken(@RequestParam
|
||||
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
||||
if (!allowedRequestMethods.contains(HttpMethod.GET)) {
|
||||
@ -99,7 +100,7 @@ public class TokenEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "OAuth 2.0 获取AccessToken接口", notes = "传递参数token等",httpMethod="POST")
|
||||
@RequestMapping(value = "/oauth/v20/token", method=RequestMethod.POST)
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN, method=RequestMethod.POST)
|
||||
public ResponseEntity<OAuth2AccessToken> postAccessToken(@RequestParam
|
||||
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
||||
// TokenEndpointAuthenticationFilter
|
||||
|
||||
@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.util.OAuth2Utils;
|
||||
import org.maxkey.authz.oauth2.provider.AuthorizationRequest;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
@ -77,7 +78,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@WebFilter(filterName = "TokenEndpointAuthenticationFilter", urlPatterns = "/oauth/v20/token/*")
|
||||
@WebFilter(filterName = "TokenEndpointAuthenticationFilter", urlPatterns = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN+"/*")
|
||||
public class TokenEndpointAuthenticationFilter implements Filter {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TokenEndpointAuthenticationFilter.class);
|
||||
|
||||
@ -34,6 +34,7 @@ import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
@ -69,7 +70,7 @@ public class TokenKeyEndpoint {
|
||||
* @param principal the currently authenticated user if there is one
|
||||
* @return the key used to verify tokens
|
||||
*/
|
||||
@RequestMapping(value = "/oauth/token_key", method = RequestMethod.GET)
|
||||
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN_KEY, method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public Map<String, String> getKey(Principal principal) {
|
||||
if ((principal == null || principal instanceof AnonymousAuthenticationToken) && !converter.isPublic()) {
|
||||
|
||||
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.authz.oauth2.provider.userinfo.endpoint;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.maxkey.constants.ContentType;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService;
|
||||
import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder;
|
||||
import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService;
|
||||
import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.domain.apps.oauth2.provider.ClientDetails;
|
||||
import org.maxkey.persistence.service.AppsService;
|
||||
import org.maxkey.persistence.service.UserInfoService;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.util.StringGenerator;
|
||||
import org.maxkey.web.HttpResponseAdapter;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
import com.nimbusds.jose.JWEHeader;
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
import com.nimbusds.jose.JWSHeader;
|
||||
import com.nimbusds.jwt.EncryptedJWT;
|
||||
import com.nimbusds.jwt.JWT;
|
||||
import com.nimbusds.jwt.JWTClaimsSet;
|
||||
import com.nimbusds.jwt.JWTClaimsSet.Builder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
@Api(tags = "2-1-OAuth v2.0 API文档模块")
|
||||
@Controller
|
||||
public class OpenIdConnectUserInfoEndpoint {
|
||||
final static Logger _logger = LoggerFactory.getLogger(OpenIdConnectUserInfoEndpoint.class);
|
||||
@Autowired
|
||||
@Qualifier("oauth20JdbcClientDetailsService")
|
||||
private ClientDetailsService clientDetailsService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("oauth20TokenServices")
|
||||
private DefaultTokenServices oauth20tokenServices;
|
||||
|
||||
|
||||
@Autowired
|
||||
@Qualifier("userInfoService")
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("appsService")
|
||||
protected AppsService appsService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("jwtSignerValidationService")
|
||||
private JwtSigningAndValidationService jwtSignerValidationService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("jwtEncryptionService")
|
||||
private JwtEncryptionAndDecryptionService jwtEnDecryptionService;
|
||||
|
||||
|
||||
|
||||
private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder
|
||||
=new SymmetricSigningAndValidationServiceBuilder();
|
||||
|
||||
private RecipientJwtEncryptionAndDecryptionServiceBuilder recipientJwtEnDecryptionServiceBuilder
|
||||
=new RecipientJwtEncryptionAndDecryptionServiceBuilder();
|
||||
|
||||
OAuthDefaultUserInfoAdapter defaultOAuthUserInfoAdapter=new OAuthDefaultUserInfoAdapter();
|
||||
|
||||
@Autowired
|
||||
protected HttpResponseAdapter httpResponseAdapter;
|
||||
|
||||
@ApiOperation(value = "OIDC 用户信息接口", notes = "传递Authorization参数access_token",httpMethod="GET")
|
||||
@RequestMapping(value=OAuth2Constants.ENDPOINT.ENDPOINT_OPENID_CONNECT_USERINFO)
|
||||
@ResponseBody
|
||||
public String connect10aUserInfo(
|
||||
@RequestHeader(value = "Authorization", required = true) String access_token,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
String principal="";
|
||||
if (!StringGenerator.uuidMatches(access_token)) {
|
||||
return JsonUtils.gson2Json(accessTokenFormatError(access_token));
|
||||
}
|
||||
|
||||
OAuth2Authentication oAuth2Authentication =null;
|
||||
try{
|
||||
oAuth2Authentication = oauth20tokenServices.loadAuthentication(access_token);
|
||||
|
||||
principal=((SigninPrincipal)oAuth2Authentication.getPrincipal()).getUsername();
|
||||
|
||||
Set<String >scopes=oAuth2Authentication.getOAuth2Request().getScope();
|
||||
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId());
|
||||
|
||||
UserInfo userInfo=queryUserInfo(principal);
|
||||
String userJson="";
|
||||
Builder jwtClaimsSetBuilder= new JWTClaimsSet.Builder();
|
||||
|
||||
SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal();
|
||||
|
||||
jwtClaimsSetBuilder.claim("sub", userInfo.getId());
|
||||
jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId());
|
||||
|
||||
if(scopes.contains("profile")){
|
||||
jwtClaimsSetBuilder.claim("name", userInfo.getUsername());
|
||||
jwtClaimsSetBuilder.claim("preferred_username", userInfo.getDisplayName());
|
||||
jwtClaimsSetBuilder.claim("given_name", userInfo.getGivenName());
|
||||
jwtClaimsSetBuilder.claim("family_name", userInfo.getFamilyName());
|
||||
jwtClaimsSetBuilder.claim("middle_name", userInfo.getMiddleName());
|
||||
jwtClaimsSetBuilder.claim("nickname", userInfo.getNickName());
|
||||
jwtClaimsSetBuilder.claim("profile", "profile");
|
||||
jwtClaimsSetBuilder.claim("picture", "picture");
|
||||
jwtClaimsSetBuilder.claim("website", userInfo.getWebSite());
|
||||
|
||||
String gender;
|
||||
switch(userInfo.getGender()){
|
||||
case UserInfo.GENDER.MALE :
|
||||
gender="male";break;
|
||||
case UserInfo.GENDER.FEMALE :
|
||||
gender="female";break;
|
||||
default:
|
||||
gender="unknown";
|
||||
}
|
||||
jwtClaimsSetBuilder.claim("gender", gender);
|
||||
jwtClaimsSetBuilder.claim("zoneinfo", userInfo.getTimeZone());
|
||||
jwtClaimsSetBuilder.claim("locale", userInfo.getLocale());
|
||||
jwtClaimsSetBuilder.claim("updated_time", userInfo.getModifiedDate());
|
||||
jwtClaimsSetBuilder.claim("birthdate", userInfo.getBirthDate());
|
||||
}
|
||||
|
||||
if(scopes.contains("email")){
|
||||
jwtClaimsSetBuilder.claim("email", userInfo.getWorkEmail());
|
||||
jwtClaimsSetBuilder.claim("email_verified", false);
|
||||
}
|
||||
|
||||
if(scopes.contains("phone")){
|
||||
jwtClaimsSetBuilder.claim("phone_number", userInfo.getWorkPhoneNumber());
|
||||
jwtClaimsSetBuilder.claim("phone_number_verified", false);
|
||||
}
|
||||
|
||||
if(scopes.contains("address")){
|
||||
HashMap<String, String> addressFields = new HashMap<String, String>();
|
||||
addressFields.put("country", userInfo.getWorkCountry());
|
||||
addressFields.put("region", userInfo.getWorkRegion());
|
||||
addressFields.put("locality", userInfo.getWorkLocality());
|
||||
addressFields.put("street_address", userInfo.getWorkStreetAddress());
|
||||
addressFields.put("formatted", userInfo.getWorkAddressFormatted());
|
||||
addressFields.put("postal_code", userInfo.getWorkPostalCode());
|
||||
|
||||
jwtClaimsSetBuilder.claim("address", addressFields);
|
||||
}
|
||||
|
||||
jwtClaimsSetBuilder
|
||||
.jwtID(UUID.randomUUID().toString())// set a random NONCE in the middle of it
|
||||
.audience(Arrays.asList(clientDetails.getClientId()))
|
||||
.issueTime(new Date())
|
||||
.expirationTime(new Date(new Date().getTime()+clientDetails.getAccessTokenValiditySeconds()*1000));
|
||||
|
||||
JWTClaimsSet userInfoJWTClaims = jwtClaimsSetBuilder.build();
|
||||
JWT userInfoJWT=null;
|
||||
JWSAlgorithm signingAlg = jwtSignerValidationService.getDefaultSigningAlgorithm();
|
||||
if (clientDetails.getUserInfoEncryptedAlgorithm() != null
|
||||
&& !clientDetails.getUserInfoEncryptedAlgorithm().equals("none")
|
||||
&& clientDetails.getUserInfoEncryptionMethod() != null
|
||||
&& !clientDetails.getUserInfoEncryptionMethod().equals("none")
|
||||
&&clientDetails.getJwksUri()!=null&&clientDetails.getJwksUri().length()>4
|
||||
) {
|
||||
//需要加密
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
JwtEncryptionAndDecryptionService recipientJwtEnDecryptionService =
|
||||
recipientJwtEnDecryptionServiceBuilder.serviceBuilder(clientDetails.getJwksUri());
|
||||
|
||||
if (recipientJwtEnDecryptionService != null) {
|
||||
JWEAlgorithm jweAlgorithm=new JWEAlgorithm(clientDetails.getUserInfoEncryptedAlgorithm());
|
||||
EncryptionMethod encryptionMethod=new EncryptionMethod(clientDetails.getUserInfoEncryptionMethod());
|
||||
EncryptedJWT encryptedJWT = new EncryptedJWT(new JWEHeader(jweAlgorithm, encryptionMethod), userInfoJWTClaims);
|
||||
recipientJwtEnDecryptionService.encryptJwt(encryptedJWT);
|
||||
userJson=encryptedJWT.serialize();
|
||||
}else{
|
||||
_logger.error("Couldn't find encrypter for client: " + clientDetails.getClientId());
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
authzException.put(OAuth2Exception.ERROR, "error");
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,"Couldn't find encrypter for client: " + clientDetails.getClientId());
|
||||
return JsonUtils.gson2Json(authzException);
|
||||
}
|
||||
}else if (clientDetails.getUserInfoSigningAlgorithm()!=null
|
||||
&& !clientDetails.getUserInfoSigningAlgorithm().equals("none")) {
|
||||
//需要签名
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
// signed ID token
|
||||
if (signingAlg.equals(JWSAlgorithm.HS256)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS384)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
||||
// sign it with the client's secret
|
||||
String client_secret=ReciprocalUtils.decoder(clientDetails.getClientSecret());
|
||||
|
||||
JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret);
|
||||
if(symmetricJwtSignerService!=null){
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT);
|
||||
}else{
|
||||
_logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret");
|
||||
}
|
||||
} else {
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
// sign it with the server's key
|
||||
jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT);
|
||||
}
|
||||
userJson=userInfoJWT.serialize();
|
||||
}else {
|
||||
//不需要加密和签名
|
||||
response.setContentType(ContentType.APPLICATION_JSON_UTF8);
|
||||
// unsigned ID token
|
||||
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
|
||||
userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims());
|
||||
}
|
||||
|
||||
return userJson;
|
||||
|
||||
}catch(OAuth2Exception e){
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode());
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,e.getMessage());
|
||||
return JsonUtils.object2Json(authzException);
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String,Object> accessTokenFormatError(String access_token){
|
||||
HashMap<String,Object>atfe=new HashMap<String,Object>();
|
||||
atfe.put(OAuth2Exception.ERROR, "token Format Invalid");
|
||||
atfe.put(OAuth2Exception.DESCRIPTION, "access Token Format Invalid , access_token : "+access_token);
|
||||
|
||||
return atfe;
|
||||
}
|
||||
|
||||
public UserInfo queryUserInfo(String uid){
|
||||
_logger.debug("uid : "+uid);
|
||||
UserInfo userInfo = (UserInfo) userInfoService.loadByUsername(uid);
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
public void setOauth20tokenServices(DefaultTokenServices oauth20tokenServices) {
|
||||
this.oauth20tokenServices = oauth20tokenServices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setUserInfoService(UserInfoService userInfoService) {
|
||||
this.userInfoService = userInfoService;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// public void setJwtSignerValidationService(
|
||||
// JwtSigningAndValidationService jwtSignerValidationService) {
|
||||
// this.jwtSignerValidationService = jwtSignerValidationService;
|
||||
// }
|
||||
//
|
||||
// public void setJwtEnDecryptionService(
|
||||
// JwtEncryptionAndDecryptionService jwtEnDecryptionService) {
|
||||
// this.jwtEnDecryptionService = jwtEnDecryptionService;
|
||||
// }
|
||||
}
|
||||
@ -17,32 +17,24 @@
|
||||
|
||||
package org.maxkey.authz.oauth2.provider.userinfo.endpoint;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.maxkey.constants.Boolean;
|
||||
import org.maxkey.constants.ContentType;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.crypto.jwt.encryption.service.JwtEncryptionAndDecryptionService;
|
||||
import org.maxkey.crypto.jwt.encryption.service.impl.RecipientJwtEncryptionAndDecryptionServiceBuilder;
|
||||
import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService;
|
||||
import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.domain.apps.Apps;
|
||||
import org.maxkey.domain.apps.oauth2.provider.ClientDetails;
|
||||
import org.maxkey.persistence.service.AppsService;
|
||||
import org.maxkey.persistence.service.UserInfoService;
|
||||
import org.maxkey.util.AuthorizationHeaderUtils;
|
||||
@ -50,7 +42,6 @@ import org.maxkey.util.Instance;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.util.StringGenerator;
|
||||
import org.maxkey.web.HttpResponseAdapter;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -59,26 +50,11 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
import com.nimbusds.jose.JWEHeader;
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
import com.nimbusds.jose.JWSHeader;
|
||||
import com.nimbusds.jwt.EncryptedJWT;
|
||||
import com.nimbusds.jwt.JWT;
|
||||
import com.nimbusds.jwt.JWTClaimsSet;
|
||||
import com.nimbusds.jwt.JWTClaimsSet.Builder;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
@Api(tags = "2-1-OAuth v2.0 API文档模块")
|
||||
@Controller
|
||||
@RequestMapping(value = { "/api" })
|
||||
public class UserInfoEndpoint {
|
||||
final static Logger _logger = LoggerFactory.getLogger(UserInfoEndpoint.class);
|
||||
@Autowired
|
||||
@ -120,7 +96,7 @@ public class UserInfoEndpoint {
|
||||
protected HttpResponseAdapter httpResponseAdapter;
|
||||
|
||||
@ApiOperation(value = "OAuth 2.0 用户信息接口", notes = "传递参数access_token",httpMethod="GET")
|
||||
@RequestMapping(value="/oauth/v20/me")
|
||||
@RequestMapping(value=OAuth2Constants.ENDPOINT.ENDPOINT_USERINFO)
|
||||
public void apiV20UserInfo(
|
||||
@RequestParam(value = "access_token", required = false) String access_token,
|
||||
@RequestHeader(value = "authorization", required = false) String authorization_bearer,
|
||||
@ -173,162 +149,6 @@ public class UserInfoEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "OIDC 用户信息接口", notes = "传递Authorization参数access_token",httpMethod="GET")
|
||||
@RequestMapping(value="/connect/v10/userinfo")
|
||||
@ResponseBody
|
||||
public String connect10aUserInfo(
|
||||
@RequestHeader(value = "Authorization", required = true) String access_token,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
String principal="";
|
||||
if (!StringGenerator.uuidMatches(access_token)) {
|
||||
return JsonUtils.gson2Json(accessTokenFormatError(access_token));
|
||||
}
|
||||
|
||||
OAuth2Authentication oAuth2Authentication =null;
|
||||
try{
|
||||
oAuth2Authentication = oauth20tokenServices.loadAuthentication(access_token);
|
||||
|
||||
principal=((SigninPrincipal)oAuth2Authentication.getPrincipal()).getUsername();
|
||||
|
||||
Set<String >scopes=oAuth2Authentication.getOAuth2Request().getScope();
|
||||
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(oAuth2Authentication.getOAuth2Request().getClientId());
|
||||
|
||||
UserInfo userInfo=queryUserInfo(principal);
|
||||
String userJson="";
|
||||
Builder jwtClaimsSetBuilder= new JWTClaimsSet.Builder();
|
||||
|
||||
SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal();
|
||||
|
||||
jwtClaimsSetBuilder.claim("sub", userInfo.getId());
|
||||
jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId());
|
||||
|
||||
if(scopes.contains("profile")){
|
||||
jwtClaimsSetBuilder.claim("name", userInfo.getUsername());
|
||||
jwtClaimsSetBuilder.claim("preferred_username", userInfo.getDisplayName());
|
||||
jwtClaimsSetBuilder.claim("given_name", userInfo.getGivenName());
|
||||
jwtClaimsSetBuilder.claim("family_name", userInfo.getFamilyName());
|
||||
jwtClaimsSetBuilder.claim("middle_name", userInfo.getMiddleName());
|
||||
jwtClaimsSetBuilder.claim("nickname", userInfo.getNickName());
|
||||
jwtClaimsSetBuilder.claim("profile", "profile");
|
||||
jwtClaimsSetBuilder.claim("picture", "picture");
|
||||
jwtClaimsSetBuilder.claim("website", userInfo.getWebSite());
|
||||
|
||||
String gender;
|
||||
switch(userInfo.getGender()){
|
||||
case UserInfo.GENDER.MALE :
|
||||
gender="male";break;
|
||||
case UserInfo.GENDER.FEMALE :
|
||||
gender="female";break;
|
||||
default:
|
||||
gender="unknown";
|
||||
}
|
||||
jwtClaimsSetBuilder.claim("gender", gender);
|
||||
jwtClaimsSetBuilder.claim("zoneinfo", userInfo.getTimeZone());
|
||||
jwtClaimsSetBuilder.claim("locale", userInfo.getLocale());
|
||||
jwtClaimsSetBuilder.claim("updated_time", userInfo.getModifiedDate());
|
||||
jwtClaimsSetBuilder.claim("birthdate", userInfo.getBirthDate());
|
||||
}
|
||||
|
||||
if(scopes.contains("email")){
|
||||
jwtClaimsSetBuilder.claim("email", userInfo.getWorkEmail());
|
||||
jwtClaimsSetBuilder.claim("email_verified", false);
|
||||
}
|
||||
|
||||
if(scopes.contains("phone")){
|
||||
jwtClaimsSetBuilder.claim("phone_number", userInfo.getWorkPhoneNumber());
|
||||
jwtClaimsSetBuilder.claim("phone_number_verified", false);
|
||||
}
|
||||
|
||||
if(scopes.contains("address")){
|
||||
HashMap<String, String> addressFields = new HashMap<String, String>();
|
||||
addressFields.put("country", userInfo.getWorkCountry());
|
||||
addressFields.put("region", userInfo.getWorkRegion());
|
||||
addressFields.put("locality", userInfo.getWorkLocality());
|
||||
addressFields.put("street_address", userInfo.getWorkStreetAddress());
|
||||
addressFields.put("formatted", userInfo.getWorkAddressFormatted());
|
||||
addressFields.put("postal_code", userInfo.getWorkPostalCode());
|
||||
|
||||
jwtClaimsSetBuilder.claim("address", addressFields);
|
||||
}
|
||||
|
||||
jwtClaimsSetBuilder
|
||||
.jwtID(UUID.randomUUID().toString())// set a random NONCE in the middle of it
|
||||
.audience(Arrays.asList(clientDetails.getClientId()))
|
||||
.issueTime(new Date())
|
||||
.expirationTime(new Date(new Date().getTime()+clientDetails.getAccessTokenValiditySeconds()*1000));
|
||||
|
||||
JWTClaimsSet userInfoJWTClaims = jwtClaimsSetBuilder.build();
|
||||
JWT userInfoJWT=null;
|
||||
JWSAlgorithm signingAlg = jwtSignerValidationService.getDefaultSigningAlgorithm();
|
||||
if (clientDetails.getUserInfoEncryptedAlgorithm() != null
|
||||
&& !clientDetails.getUserInfoEncryptedAlgorithm().equals("none")
|
||||
&& clientDetails.getUserInfoEncryptionMethod() != null
|
||||
&& !clientDetails.getUserInfoEncryptionMethod().equals("none")
|
||||
&&clientDetails.getJwksUri()!=null&&clientDetails.getJwksUri().length()>4
|
||||
) {
|
||||
//需要加密
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
JwtEncryptionAndDecryptionService recipientJwtEnDecryptionService =
|
||||
recipientJwtEnDecryptionServiceBuilder.serviceBuilder(clientDetails.getJwksUri());
|
||||
|
||||
if (recipientJwtEnDecryptionService != null) {
|
||||
JWEAlgorithm jweAlgorithm=new JWEAlgorithm(clientDetails.getUserInfoEncryptedAlgorithm());
|
||||
EncryptionMethod encryptionMethod=new EncryptionMethod(clientDetails.getUserInfoEncryptionMethod());
|
||||
EncryptedJWT encryptedJWT = new EncryptedJWT(new JWEHeader(jweAlgorithm, encryptionMethod), userInfoJWTClaims);
|
||||
recipientJwtEnDecryptionService.encryptJwt(encryptedJWT);
|
||||
userJson=encryptedJWT.serialize();
|
||||
}else{
|
||||
_logger.error("Couldn't find encrypter for client: " + clientDetails.getClientId());
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
authzException.put(OAuth2Exception.ERROR, "error");
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,"Couldn't find encrypter for client: " + clientDetails.getClientId());
|
||||
return JsonUtils.gson2Json(authzException);
|
||||
}
|
||||
}else if (clientDetails.getUserInfoSigningAlgorithm()!=null
|
||||
&& !clientDetails.getUserInfoSigningAlgorithm().equals("none")) {
|
||||
//需要签名
|
||||
response.setContentType(ContentType.APPLICATION_JWT_UTF8);
|
||||
// signed ID token
|
||||
if (signingAlg.equals(JWSAlgorithm.HS256)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS384)
|
||||
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
||||
// sign it with the client's secret
|
||||
String client_secret=ReciprocalUtils.decoder(clientDetails.getClientSecret());
|
||||
|
||||
JwtSigningAndValidationService symmetricJwtSignerService =symmetricJwtSignerServiceBuilder.serviceBuilder(client_secret);
|
||||
if(symmetricJwtSignerService!=null){
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", "SYMMETRIC-KEY").build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
symmetricJwtSignerService.signJwt((SignedJWT) userInfoJWT);
|
||||
}else{
|
||||
_logger.error("Couldn't create symmetric validator for client " + clientDetails.getClientId() + " without a client secret");
|
||||
}
|
||||
} else {
|
||||
userInfoJWTClaims = new JWTClaimsSet.Builder(userInfoJWTClaims).claim("kid", jwtSignerValidationService.getDefaultSignerKeyId()).build();
|
||||
userInfoJWT = new SignedJWT(new JWSHeader(signingAlg), userInfoJWTClaims);
|
||||
// sign it with the server's key
|
||||
jwtSignerValidationService.signJwt((SignedJWT) userInfoJWT);
|
||||
}
|
||||
userJson=userInfoJWT.serialize();
|
||||
}else {
|
||||
//不需要加密和签名
|
||||
response.setContentType(ContentType.APPLICATION_JSON_UTF8);
|
||||
// unsigned ID token
|
||||
//userInfoJWT = new PlainJWT(userInfoJWTClaims);
|
||||
userJson=JsonUtils.gson2Json(jwtClaimsSetBuilder.getClaims());
|
||||
}
|
||||
|
||||
return userJson;
|
||||
|
||||
}catch(OAuth2Exception e){
|
||||
HashMap<String,Object>authzException=new HashMap<String,Object>();
|
||||
authzException.put(OAuth2Exception.ERROR, e.getOAuth2ErrorCode());
|
||||
authzException.put(OAuth2Exception.DESCRIPTION,e.getMessage());
|
||||
return JsonUtils.object2Json(authzException);
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String,Object> accessTokenFormatError(String access_token){
|
||||
HashMap<String,Object>atfe=new HashMap<String,Object>();
|
||||
atfe.put(OAuth2Exception.ERROR, "token Format Invalid");
|
||||
|
||||
@ -24,6 +24,7 @@ import java.security.spec.InvalidKeySpecException;
|
||||
import javax.servlet.Filter;
|
||||
import javax.sql.DataSource;
|
||||
import org.maxkey.authn.support.jwt.JwtLoginService;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore;
|
||||
@ -79,7 +80,7 @@ public class Oauth20AutoConfiguration implements InitializingBean {
|
||||
_logger.debug("TokenEndpointAuthenticationFilter init ");
|
||||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();
|
||||
registration.setFilter(new TokenEndpointAuthenticationFilter());
|
||||
registration.addUrlPatterns("/oauth/v20/token/*");
|
||||
registration.addUrlPatterns(OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN + "/*");
|
||||
registration.setName("TokenEndpointAuthenticationFilter");
|
||||
registration.setOrder(1);
|
||||
return registration;
|
||||
|
||||
@ -212,8 +212,8 @@ maxkey.saml.v20.sp.issuing.entity.id=client.maxkey.org
|
||||
#OIDC V1.0 METADATA configuration #
|
||||
#############################################################################
|
||||
maxkey.oidc.metadata.issuer=https://${maxkey.server.domain}/maxkey
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token
|
||||
maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo
|
||||
|
||||
#############################################################################
|
||||
|
||||
@ -180,8 +180,8 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
|
||||
.excludePathPatterns("/authz/cas/v1/tickets/*")
|
||||
|
||||
//OAuth
|
||||
.addPathPatterns("/oauth/v20/authorize")
|
||||
.addPathPatterns("/oauth/v20/authorize/*")
|
||||
.addPathPatterns("/authz/oauth/v20/authorize")
|
||||
.addPathPatterns("/authz/oauth/v20/authorize/*")
|
||||
|
||||
//online ticket Validate
|
||||
.excludePathPatterns("/onlineticket/ticketValidate")
|
||||
|
||||
@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
|
||||
#OIDC V1.0 METADATA configuration #
|
||||
#############################################################################
|
||||
maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token
|
||||
maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo
|
||||
|
||||
#############################################################################
|
||||
|
||||
@ -287,8 +287,8 @@ maxkey.support.wsfederation.logoutUrl=https://adfs.maxkey.top/adfs/ls/?wa=wsigno
|
||||
#OIDC V1.0 METADATA configuration #
|
||||
#############################################################################
|
||||
maxkey.oidc.metadata.issuer=${maxkey.server.name}/maxkey
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/oauth/v20/token
|
||||
maxkey.oidc.metadata.authorizationEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/authorize
|
||||
maxkey.oidc.metadata.tokenEndpoint=${maxkey.server.name}/maxkey/authz/oauth/v20/token
|
||||
maxkey.oidc.metadata.userinfoEndpoint=${maxkey.server.name}/maxkey/api/connect/userinfo
|
||||
|
||||
#############################################################################
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
{
|
||||
"issuer": "http://login.connsec.com",
|
||||
"authorization_endpoint": "http://login.connsec.com/sec/oauth/v20/authorize",
|
||||
"token_endpoint": "http://login.connsec.com/sec/oauth/v20/token",
|
||||
"userinfo_endpoint": "http://login.connsec.com/sec/api/connect/v10/userinfo",
|
||||
"issuer": "http://sso.maxkey.top",
|
||||
"authorization_endpoint": "http://sso.maxkey.top/maxkey/authz/oauth/v20/authorize",
|
||||
"token_endpoint": "http://sso.maxkey.top/maxkey/authz/oauth/v20/token",
|
||||
"userinfo_endpoint": "http://sso.maxkey.top/maxkey/api/connect/v10/userinfo",
|
||||
"revocation_endpoint": "",
|
||||
"jwks_uri": "http://login.connsec.com/sec/key/jwk",
|
||||
"jwks_uri": "http://sso.maxkey.top/maxkey/key/jwk",
|
||||
"display_values_supported": [
|
||||
"page",
|
||||
"popup",
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
</table>
|
||||
|
||||
<!--<p>You hereby authorize "${model.client.clientId!}" to access your protected resources.</p>-->
|
||||
<form id="confirmationForm" name="confirmationForm" action="<@base/>/oauth/v20/authorize" method="post">
|
||||
<form id="confirmationForm" name="confirmationForm" action="<@base/>/authz/oauth/v20/authorize" method="post">
|
||||
<input id="user_oauth_approval" name="user_oauth_approval" value="true" type="hidden"/>
|
||||
<label><input class="button btn btn-primary mr-3" name="authorize" value='<@locale code="apps.oauth.approval.authorize"/>' type="submit"/></label>
|
||||
</form>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user