Browse Source

Merge branch 'develop' of gitadmin/tuoheng_oidc into release

tags/V2.2.0
gitadmin 2 years ago
parent
commit
d8f5223840
12 changed files with 523 additions and 7 deletions
  1. +1
    -1
      tuoheng_oidc_server/src/main/java/com/tuoheng/SpringAuthorizationServerApplication.java
  2. +44
    -6
      tuoheng_oidc_server/src/main/java/com/tuoheng/config/SecurityConfig.java
  3. +11
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/controller/UserController.java
  4. +3
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/mapper/UserMapper.java
  5. +23
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/model/param/GetUserInfoDto.java
  6. +69
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2EndpointUtils.java
  7. +89
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationConverter.java
  8. +186
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationProvider.java
  9. +75
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationToken.java
  10. +3
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/service/UserSevice.java
  11. +12
    -0
      tuoheng_oidc_server/src/main/java/com/tuoheng/service/impl/UserServiceImpl.java
  12. +7
    -0
      tuoheng_oidc_server/src/main/resources/mapper/UserMapper.xml

+ 1
- 1
tuoheng_oidc_server/src/main/java/com/tuoheng/SpringAuthorizationServerApplication.java View File

@@ -7,7 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
public class SpringAuthorizationServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAuthorizationServerApplication.class, args);
System.out.println("TuoHeng-Oidc启动成功~");
System.out.println("TuoHeng-Oidc-Server启动成功~");
}

}

+ 44
- 6
tuoheng_oidc_server/src/main/java/com/tuoheng/config/SecurityConfig.java View File

@@ -1,24 +1,36 @@
package com.tuoheng.config;

import com.tuoheng.oauth2.authentication.OAuth2ResourceOwnerPasswordAuthenticationConverter;
import com.tuoheng.handler.AccessDeniedHandler;
import com.tuoheng.mapper.UserMapper;
import com.tuoheng.model.dto.UserBaseInfoDto;
//import com.tuoheng.oauth2.authentication.OAuth2ResourceOwnerPasswordAuthenticationProvider;
import com.tuoheng.oauth2.authentication.OAuth2ResourceOwnerPasswordAuthenticationProvider;
import com.tuoheng.service.impl.OidcUserInfoServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.core.OAuth2Token;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.security.oauth2.server.authorization.web.authentication.DelegatingAuthenticationConverter;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeAuthenticationConverter;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ClientCredentialsAuthenticationConverter;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2RefreshTokenAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@@ -27,6 +39,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.function.Function;

/**
@@ -51,6 +64,14 @@ public class SecurityConfig {
OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer<>();

http.apply(authorizationServerConfigurer
.tokenEndpoint((tokenEndpoint) -> tokenEndpoint.accessTokenRequestConverter(new DelegatingAuthenticationConverter(
Arrays.asList(
new OAuth2AuthorizationCodeAuthenticationConverter(),
new OAuth2RefreshTokenAuthenticationConverter(),
new OAuth2ClientCredentialsAuthenticationConverter(),
new OAuth2ResourceOwnerPasswordAuthenticationConverter())))));

OidcUserInfoServiceImpl oidcUserInfoService = new OidcUserInfoServiceImpl();
//自定义用户映射器
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> {
@@ -65,7 +86,7 @@ public class SecurityConfig {

RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();

return http.requestMatcher(endpointsMatcher)
http.requestMatcher(endpointsMatcher)
.authorizeRequests((authorizeRequests) -> {
((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl) authorizeRequests.anyRequest()).authenticated();
}).csrf((csrf) -> {
@@ -77,9 +98,10 @@ public class SecurityConfig {
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/toLogin"))
.accessDeniedHandler(new AccessDeniedHandler()))
//.authenticationEntryPoint(new AuthenticationEntryPoint()))
.apply(authorizationServerConfigurer)
.and()
.build();
.apply(authorizationServerConfigurer);
SecurityFilterChain securityFilterChain = http.build();
addCustomOAuth2ResourceOwnerPasswordAuthenticationProvider(http);
return securityFilterChain;
}

@Bean
@@ -90,7 +112,7 @@ public class SecurityConfig {
http.csrf().disable()
.authorizeHttpRequests((authorize) -> authorize
.antMatchers("/toLogin", "/getHealth", "/static/**", "/vercode").permitAll()
.antMatchers("/user/create").permitAll()
.antMatchers("/user/create","/user/getInfo").permitAll()
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
@@ -101,7 +123,8 @@ public class SecurityConfig {
.loginProcessingUrl("/login")
)
.logout()
.logoutSuccessUrl("/toLogout");
.logoutSuccessUrl("/toLogout")
.and();

return http.build();
}
@@ -129,4 +152,19 @@ public class SecurityConfig {
return new BCryptPasswordEncoder();
}*/

@SuppressWarnings("unchecked")
private void addCustomOAuth2ResourceOwnerPasswordAuthenticationProvider(HttpSecurity http) {

AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator = http.getSharedObject(OAuth2TokenGenerator.class);

OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider =
new OAuth2ResourceOwnerPasswordAuthenticationProvider(authenticationManager, authorizationService, tokenGenerator);

// This will add new authentication provider in the list of existing authentication providers.
http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);

}

}

+ 11
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/controller/UserController.java View File

@@ -1,6 +1,7 @@
package com.tuoheng.controller;

import com.tuoheng.model.param.CreateUserDto;
import com.tuoheng.model.param.GetUserInfoDto;
import com.tuoheng.service.UserSevice;
import com.tuoheng.until.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,4 +25,14 @@ public class UserController {
return userSevice.createUser(createUserDto);
}

/**
* 小程序端获取用户信息端点
* @param getUserInfoDto
* @return
*/
@PostMapping("/getInfo")
public JsonResult getUserInfo(@RequestBody GetUserInfoDto getUserInfoDto){
return userSevice.getUserInfo(getUserInfoDto);
}

}

+ 3
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/mapper/UserMapper.java View File

@@ -16,4 +16,7 @@ public interface UserMapper {

UserBaseInfoDto getUserBaseInfo(String username);

UserBaseInfoDto getMpUserInfo(String username);


}

+ 23
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/model/param/GetUserInfoDto.java View File

@@ -0,0 +1,23 @@
package com.tuoheng.model.param;

import lombok.Data;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/10/8 11:30
*/
@Data
public class GetUserInfoDto {

@NotEmpty(message = "username can not be empty!")
private String username;

@NotEmpty(message = "token can not be empty!")
private String token;

}

+ 69
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2EndpointUtils.java View File

@@ -0,0 +1,69 @@
package com.tuoheng.oauth2.authentication;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
* Utility methods for the OAuth 2.0 Protocol Endpoints.
*
* @author Joe Grandja
* @since 0.1.2
*/
final class OAuth2EndpointUtils {
static final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2";

private OAuth2EndpointUtils() {
}

static MultiValueMap<String, String> getParameters(HttpServletRequest request) {
Map<String, String[]> parameterMap = request.getParameterMap();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(parameterMap.size());
parameterMap.forEach((key, values) -> {
if (values.length > 0) {
for (String value : values) {
parameters.add(key, value);
}
}
});
return parameters;
}

static Map<String, Object> getParametersIfMatchesAuthorizationCodeGrantRequest(HttpServletRequest request, String... exclusions) {
if (!matchesAuthorizationCodeGrantRequest(request)) {
return Collections.emptyMap();
}
Map<String, Object> parameters = new HashMap<>(getParameters(request).toSingleValueMap());
for (String exclusion : exclusions) {
parameters.remove(exclusion);
}
return parameters;
}

static boolean matchesAuthorizationCodeGrantRequest(HttpServletRequest request) {
return AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(
request.getParameter(OAuth2ParameterNames.GRANT_TYPE)) &&
request.getParameter(OAuth2ParameterNames.CODE) != null;
}

static boolean matchesPkceTokenRequest(HttpServletRequest request) {
return matchesAuthorizationCodeGrantRequest(request) &&
request.getParameter(PkceParameterNames.CODE_VERIFIER) != null;
}

static void throwError(String errorCode, String parameterName, String errorUri) {
OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, errorUri);
throw new OAuth2AuthenticationException(error);
}

}

+ 89
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationConverter.java View File

@@ -0,0 +1,89 @@
package com.tuoheng.oauth2.authentication;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

public class OAuth2ResourceOwnerPasswordAuthenticationConverter implements AuthenticationConverter {

@Nullable
@Override
public Authentication convert(HttpServletRequest request) {
// grant_type (REQUIRED)
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (!AuthorizationGrantType.PASSWORD.getValue().equals(grantType)) {
return null;
}

MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);

// scope (OPTIONAL)
String scope = parameters.getFirst(OAuth2ParameterNames.SCOPE);
if (StringUtils.hasText(scope) &&
parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) {
OAuth2EndpointUtils.throwError(
OAuth2ErrorCodes.INVALID_REQUEST,
OAuth2ParameterNames.SCOPE,
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
}
Set<String> requestedScopes = null;
if (StringUtils.hasText(scope)) {
requestedScopes = new HashSet<>(
Arrays.asList(StringUtils.delimitedListToStringArray(scope, " ")));
}
// username (REQUIRED)
String username = parameters.getFirst(OAuth2ParameterNames.USERNAME);
if (!StringUtils.hasText(username) || parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) {
OAuth2EndpointUtils.throwError(
OAuth2ErrorCodes.INVALID_REQUEST,
OAuth2ParameterNames.USERNAME,
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
}
// password (REQUIRED)
String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD);
if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) {
OAuth2EndpointUtils.throwError(
OAuth2ErrorCodes.INVALID_REQUEST,
OAuth2ParameterNames.PASSWORD,
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
}
Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication();
if (clientPrincipal == null) {
OAuth2EndpointUtils.throwError(
OAuth2ErrorCodes.INVALID_REQUEST,
OAuth2ErrorCodes.INVALID_CLIENT,
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI);
}
Map<String, Object> additionalParameters = parameters
.entrySet()
.stream()
.filter(e -> !e.getKey().equals(OAuth2ParameterNames.GRANT_TYPE) &&
!e.getKey().equals(OAuth2ParameterNames.SCOPE))
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0)));
return new OAuth2ResourceOwnerPasswordAuthenticationToken(
AuthorizationGrantType.PASSWORD, clientPrincipal, requestedScopes, additionalParameters);

}
}

+ 186
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationProvider.java View File

@@ -0,0 +1,186 @@
package com.tuoheng.oauth2.authentication;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.*;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.context.ProviderContextHolder;
import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.security.Principal;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class OAuth2ResourceOwnerPasswordAuthenticationProvider implements AuthenticationProvider {

private static final Logger LOGGER = LogManager.getLogger();

private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2";
private final AuthenticationManager authenticationManager;
private final OAuth2AuthorizationService authorizationService;
private final OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator;

/**
* Constructs an {@code OAuth2ResourceOwnerPasswordAuthenticationProviderNew} using the provided parameters.
*
* @param authenticationManager the authentication manager
* @param authorizationService the authorization service
* @param tokenGenerator the token generator
* @since 0.2.3
*/
public OAuth2ResourceOwnerPasswordAuthenticationProvider(AuthenticationManager authenticationManager,
OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator) {
Assert.notNull(authorizationService, "authorizationService cannot be null");
Assert.notNull(tokenGenerator, "tokenGenerator cannot be null");
this.authenticationManager = authenticationManager;
this.authorizationService = authorizationService;
this.tokenGenerator = tokenGenerator;
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

OAuth2ResourceOwnerPasswordAuthenticationToken resouceOwnerPasswordAuthentication = (OAuth2ResourceOwnerPasswordAuthenticationToken) authentication;

OAuth2ClientAuthenticationToken clientPrincipal = getAuthenticatedClientElseThrowInvalidClient(resouceOwnerPasswordAuthentication);

RegisteredClient registeredClient = clientPrincipal.getRegisteredClient();

if (!registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.PASSWORD)) {
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
}

Authentication usernamePasswordAuthentication = getUsernamePasswordAuthentication(resouceOwnerPasswordAuthentication);

Set<String> authorizedScopes = registeredClient.getScopes(); // Default to configured scopes
Set<String> requestedScopes = resouceOwnerPasswordAuthentication.getScopes();
if (!CollectionUtils.isEmpty(requestedScopes)) {
Set<String> unauthorizedScopes = requestedScopes.stream()
.filter(requestedScope -> !registeredClient.getScopes().contains(requestedScope))
.collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(unauthorizedScopes)) {
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_SCOPE);
}

authorizedScopes = new LinkedHashSet<>(requestedScopes);
}

// @formatter:off
DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder()
.registeredClient(registeredClient)
.principal(usernamePasswordAuthentication)
.providerContext(ProviderContextHolder.getProviderContext())
.authorizedScopes(authorizedScopes)
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.authorizationGrant(resouceOwnerPasswordAuthentication);
// @formatter:on

// ----- Access token -----
OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).build();
OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext);
if (generatedAccessToken == null) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
"The token generator failed to generate the access token.", ERROR_URI);
throw new OAuth2AuthenticationException(error);
}

OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(),
generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes());

// ----- Refresh token -----
OAuth2RefreshToken refreshToken = null;
if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) &&
// Do not issue refresh token to public client
!clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) {

tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build();
OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext);
if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
"The token generator failed to generate the refresh token.", ERROR_URI);
throw new OAuth2AuthenticationException(error);
}
refreshToken = (OAuth2RefreshToken) generatedRefreshToken;

}

// @formatter:off
OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
.principalName(usernamePasswordAuthentication.getName())
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizedScopes)
.attribute(Principal.class.getName(), usernamePasswordAuthentication);
// @formatter:on
if (generatedAccessToken instanceof ClaimAccessor) {
authorizationBuilder.token(accessToken, (metadata) ->
metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, ((ClaimAccessor) generatedAccessToken).getClaims()));
} else {
authorizationBuilder.accessToken(accessToken);
}

OAuth2Authorization authorization = authorizationBuilder.build();

this.authorizationService.save(authorization);

LOGGER.debug("OAuth2Authorization saved successfully");

Map<String, Object> additionalParameters = Collections.emptyMap();

LOGGER.debug("returning OAuth2AccessTokenAuthenticationToken");

return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, additionalParameters);
}

@Override
public boolean supports(Class<?> authentication) {
return OAuth2ResourceOwnerPasswordAuthenticationToken.class.isAssignableFrom(authentication);
}

private Authentication getUsernamePasswordAuthentication(OAuth2ResourceOwnerPasswordAuthenticationToken resouceOwnerPasswordAuthentication) {

Map<String, Object> additionalParameters = resouceOwnerPasswordAuthentication.getAdditionalParameters();

String username = (String) additionalParameters.get(OAuth2ParameterNames.USERNAME);
String password = (String) additionalParameters.get(OAuth2ParameterNames.PASSWORD);

UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, password);
LOGGER.debug("got usernamePasswordAuthenticationToken=" + usernamePasswordAuthenticationToken);

Authentication usernamePasswordAuthentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
return usernamePasswordAuthentication;
}

private OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) {

OAuth2ClientAuthenticationToken clientPrincipal = null;

if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) {
clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal();
}

if (clientPrincipal != null && clientPrincipal.isAuthenticated()) {
return clientPrincipal;
}

throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT);
}

}

+ 75
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/oauth2/authentication/OAuth2ResourceOwnerPasswordAuthenticationToken.java View File

@@ -0,0 +1,75 @@
package com.tuoheng.oauth2.authentication;

import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
import org.springframework.util.Assert;

import java.util.*;

public class OAuth2ResourceOwnerPasswordAuthenticationToken extends AbstractAuthenticationToken {

private static final long serialVersionUID = -6067207202119450764L;

private final AuthorizationGrantType authorizationGrantType;
private final Authentication clientPrincipal;
private final Set<String> scopes;
private final Map<String, Object> additionalParameters;

/**
* Constructs an {@code OAuth2ClientCredentialsAuthenticationToken} using the provided parameters.
*
* @param clientPrincipal the authenticated client principal
*/

public OAuth2ResourceOwnerPasswordAuthenticationToken(AuthorizationGrantType authorizationGrantType,
Authentication clientPrincipal, @Nullable Set<String> scopes, @Nullable Map<String, Object> additionalParameters) {
super(Collections.emptyList());
Assert.notNull(authorizationGrantType, "authorizationGrantType cannot be null");
Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");
this.authorizationGrantType = authorizationGrantType;
this.clientPrincipal = clientPrincipal;
this.scopes = Collections.unmodifiableSet(scopes != null ? new HashSet<>(scopes) : Collections.emptySet());
this.additionalParameters = Collections.unmodifiableMap(additionalParameters != null ? new HashMap<>(additionalParameters) : Collections.emptyMap());
}

/**
* Returns the authorization grant type.
*
* @return the authorization grant type
*/
public AuthorizationGrantType getGrantType() {
return this.authorizationGrantType;
}

@Override
public Object getPrincipal() {
return this.clientPrincipal;
}

@Override
public Object getCredentials() {
return "";
}

/**
* Returns the requested scope(s).
*
* @return the requested scope(s), or an empty {@code Set} if not available
*/
public Set<String> getScopes() {
return this.scopes;
}

/**
* Returns the additional parameters.
*
* @return the additional parameters
*/
public Map<String, Object> getAdditionalParameters() {
return this.additionalParameters;
}
}

+ 3
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/service/UserSevice.java View File

@@ -1,6 +1,7 @@
package com.tuoheng.service;

import com.tuoheng.model.param.CreateUserDto;
import com.tuoheng.model.param.GetUserInfoDto;
import com.tuoheng.until.JsonResult;
/**
* @author chenjiandong
@@ -11,4 +12,6 @@ public interface UserSevice {

JsonResult createUser(CreateUserDto createUserDto);

JsonResult getUserInfo(GetUserInfoDto getUserInfoDto);

}

+ 12
- 0
tuoheng_oidc_server/src/main/java/com/tuoheng/service/impl/UserServiceImpl.java View File

@@ -2,7 +2,9 @@ package com.tuoheng.service.impl;

import com.tuoheng.mapper.AuthoritiesMapper;
import com.tuoheng.mapper.UserMapper;
import com.tuoheng.model.dto.UserBaseInfoDto;
import com.tuoheng.model.param.CreateUserDto;
import com.tuoheng.model.param.GetUserInfoDto;
import com.tuoheng.model.po.AuthoritiesPo;
import com.tuoheng.model.po.UserPo;
import com.tuoheng.service.UserSevice;
@@ -12,6 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -54,4 +59,11 @@ public class UserServiceImpl implements UserSevice {
return JsonResult.success(userPo.getId());
}

@Override
public JsonResult getUserInfo(GetUserInfoDto getUserInfoDto){
UserBaseInfoDto userBaseInfoDto = userMapper.getMpUserInfo(getUserInfoDto.getUsername());
return JsonResult.success(userBaseInfoDto);
}


}

+ 7
- 0
tuoheng_oidc_server/src/main/resources/mapper/UserMapper.xml View File

@@ -24,4 +24,11 @@
where a.username = #{username}
</select>

<select id="getMpUserInfo" resultMap="UserBaseInfoMap">
select a.id as userId, a.username as userName, b.authority
from users a
inner join authorities b on a.id = b.user_id
where a.username = #{username}
</select>

</mapper>

Loading…
Cancel
Save