提交 db4e9b74 编写于 作者: zlt2000's avatar zlt2000

重构uaa自定义授权,统一授权所有接口使用oauth/token

上级 2b474644
......@@ -28,6 +28,6 @@ CREATE TABLE `oauth_client_details` (
-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES (1, 'webApp', NULL, '$2a$10$06msMGYRH8nrm4iVnKFNKOoddB8wOwymVhbUzw/d3ZixD7Nq8ot72', 'webApp', 'app', 'authorization_code,password,refresh_token,client_credentials', NULL, NULL, 3600, NULL, '{}', 'true', NULL, NULL, 'pc端');
INSERT INTO `oauth_client_details` VALUES (1, 'webApp', NULL, '$2a$10$06msMGYRH8nrm4iVnKFNKOoddB8wOwymVhbUzw/d3ZixD7Nq8ot72', 'webApp', 'app', 'authorization_code,password,refresh_token,client_credentials,implicit,password_code,openId,mobile_password', NULL, NULL, 3600, NULL, '{}', 'true', NULL, NULL, 'pc端');
INSERT INTO `oauth_client_details` VALUES (2, 'app', NULL, '$2a$10$i3F515wEDiB4Gvj9ym9Prui0dasRttEUQ9ink4Wpgb4zEDCAlV8zO', 'app', 'app', 'authorization_code,password,refresh_token', 'http://127.0.0.1:8081/callback.html', NULL, 3600, NULL, '{}', 'true', NULL, NULL, '移动端');
INSERT INTO `oauth_client_details` VALUES (3, 'zlt', NULL, '$2a$10$/o.wuORzVcXaezmYVzwYMuoY7qeWXBALwQmkskXD/7C6rqfCyPrna', 'zlt', 'all', 'authorization_code,password,refresh_token,client_credentials', 'http://127.0.0.1:8080/singleLogin', NULL, 3600, 28800, '{}', 'true', '2018-12-27 00:50:30', '2018-12-27 00:50:30', '第三方应用');
\ No newline at end of file
------------更新语句
Use `oauth-center`;
update oauth_client_details set authorized_grant_types = 'authorization_code,password,refresh_token,client_credentials,implicit,password_code,openId,mobile_password' where client_id = 'webApp'
\ No newline at end of file
......@@ -11,6 +11,7 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.A
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
......@@ -26,6 +27,9 @@ import java.util.Arrays;
*
* @author zlt
* @date 2018/10/24
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
@EnableAuthorizationServer
......@@ -58,6 +62,9 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Autowired
private RandomValueAuthorizationCodeServices authorizationCodeServices;
@Autowired
private TokenGranter tokenGranter;
/**
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
* @param endpoints
......@@ -78,7 +85,8 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.authorizationCodeServices(authorizationCodeServices)
.exceptionTranslator(webResponseExceptionTranslator);
.exceptionTranslator(webResponseExceptionTranslator)
.tokenGranter(tokenGranter);
}
/**
......
......@@ -33,6 +33,9 @@ import javax.annotation.Resource;
* 在WebSecurityConfigurerAdapter不拦截oauth要开放的资源
*
* @author zlt
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
@Import(DefaultPasswordConfig.class)
......@@ -53,9 +56,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private LogoutHandler oauthLogoutHandler;
@Autowired
private ValidateCodeSecurityConfig validateCodeSecurityConfig;
@Autowired
private OpenIdAuthenticationSecurityConfig openIdAuthenticationSecurityConfig;
......@@ -104,8 +104,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.addLogoutHandler(oauthLogoutHandler)
.clearAuthentication(true)
.and()
.apply(validateCodeSecurityConfig)
.and()
.apply(openIdAuthenticationSecurityConfig)
.and()
.apply(mobileAuthenticationSecurityConfig)
......
package com.central.oauth.config;
import com.central.oauth.granter.MobilePwdGranter;
import com.central.oauth.granter.OpenIdGranter;
import com.central.oauth.granter.PwdImgCodeGranter;
import com.central.oauth.service.IValidateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* token授权模式配置类
*
* @author zlt
* @date 2020/7/11
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Configuration
public class TokenGranterConfig {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired(required = false)
private TokenEnhancer tokenEnhancer;
@Autowired
private IValidateCodeService validateCodeService;
private AuthorizationCodeServices authorizationCodeServices;
private boolean reuseRefreshToken = true;
private AuthorizationServerTokenServices tokenServices;
private TokenGranter tokenGranter;
/**
* 授权模式
*/
@Bean
public TokenGranter tokenGranter() {
if (tokenGranter == null) {
tokenGranter = new TokenGranter() {
private CompositeTokenGranter delegate;
@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
if (delegate == null) {
delegate = new CompositeTokenGranter(getAllTokenGranters());
}
return delegate.grant(grantType, tokenRequest);
}
};
}
return tokenGranter;
}
/**
* 所有授权模式:默认的5种模式 + 自定义的模式
*/
private List<TokenGranter> getAllTokenGranters() {
AuthorizationServerTokenServices tokenServices = tokenServices();
AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
OAuth2RequestFactory requestFactory = requestFactory();
//获取默认的授权模式
List<TokenGranter> tokenGranters = getDefaultTokenGranters(tokenServices, authorizationCodeServices, requestFactory);
if (authenticationManager != null) {
// 添加密码加图形验证码模式
tokenGranters.add(new PwdImgCodeGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory, validateCodeService));
// 添加openId模式
tokenGranters.add(new OpenIdGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory));
// 添加手机号加密码授权模式
tokenGranters.add(new MobilePwdGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory));
}
return tokenGranters;
}
/**
* 默认的授权模式
*/
private List<TokenGranter> getDefaultTokenGranters(AuthorizationServerTokenServices tokenServices
, AuthorizationCodeServices authorizationCodeServices, OAuth2RequestFactory requestFactory) {
List<TokenGranter> tokenGranters = new ArrayList<>();
// 添加授权码模式
tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetailsService, requestFactory));
// 添加刷新令牌的模式
tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetailsService, requestFactory));
// 添加隐士授权模式
tokenGranters.add(new ImplicitTokenGranter(tokenServices, clientDetailsService, requestFactory));
// 添加客户端模式
tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, requestFactory));
if (authenticationManager != null) {
// 添加密码模式
tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory));
}
return tokenGranters;
}
private AuthorizationServerTokenServices tokenServices() {
if (tokenServices != null) {
return tokenServices;
}
this.tokenServices = createDefaultTokenServices();
return tokenServices;
}
private AuthorizationCodeServices authorizationCodeServices() {
if (authorizationCodeServices == null) {
authorizationCodeServices = new InMemoryAuthorizationCodeServices();
}
return authorizationCodeServices;
}
private OAuth2RequestFactory requestFactory() {
return new DefaultOAuth2RequestFactory(clientDetailsService);
}
private DefaultTokenServices createDefaultTokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setReuseRefreshToken(reuseRefreshToken);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setTokenEnhancer(tokenEnhancer);
addUserDetailsService(tokenServices, this.userDetailsService);
return tokenServices;
}
private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetailsService userDetailsService) {
if (userDetailsService != null) {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
tokenServices.setAuthenticationManager(new ProviderManager(Collections.singletonList(provider)));
}
}
}
/**
*
*/
package com.central.oauth.config;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.Filter;
/**
* 校验码相关安全配置
*
* @author zlt
*/
@Component("validateCodeSecurityConfig")
public class ValidateCodeSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Resource
private Filter validateCodeFilter;
@Override
public void configure(HttpSecurity http) {
http.addFilterBefore(validateCodeFilter, AbstractPreAuthenticatedProcessingFilter.class);
}
}
package com.central.oauth.controller;
import com.central.common.constant.SecurityConstants;
import com.central.common.utils.ResponseUtil;
import com.central.common.context.TenantContextHolder;
import com.central.oauth2.common.token.MobileAuthenticationToken;
import com.central.oauth2.common.token.OpenIdAuthenticationToken;
import com.central.oauth2.common.util.AuthUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* OAuth2相关操作
*
* @author zlt
*/
@Api(tags = "OAuth2相关操作")
@Slf4j
@RestController
public class OAuth2Controller {
@Resource
private ObjectMapper objectMapper;
@Autowired
private PasswordEncoder passwordEncoder;
@Resource
private AuthorizationServerTokenServices authorizationServerTokenServices;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ClientDetailsService clientDetailsService;
@ApiOperation(value = "用户名密码获取token")
@PostMapping(SecurityConstants.PASSWORD_LOGIN_PRO_URL)
public void getUserTokenInfo(
@ApiParam(required = true, name = "username", value = "账号") String username,
@ApiParam(required = true, name = "password", value = "密码") String password,
HttpServletRequest request, HttpServletResponse response) throws IOException {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
writerToken(request, response, token, "用户名或密码错误");
}
@ApiOperation(value = "openId获取token")
@PostMapping(SecurityConstants.OPENID_TOKEN_URL)
public void getTokenByOpenId(
@ApiParam(required = true, name = "openId", value = "openId") String openId,
HttpServletRequest request, HttpServletResponse response) throws IOException {
OpenIdAuthenticationToken token = new OpenIdAuthenticationToken(openId);
writerToken(request, response, token, "openId错误");
}
@ApiOperation(value = "mobile获取token")
@PostMapping(SecurityConstants.MOBILE_TOKEN_URL)
public void getTokenByMobile(
@ApiParam(required = true, name = "mobile", value = "mobile") String mobile,
@ApiParam(required = true, name = "password", value = "密码") String password,
HttpServletRequest request, HttpServletResponse response) throws IOException {
MobileAuthenticationToken token = new MobileAuthenticationToken(mobile, password);
writerToken(request, response, token, "手机号或密码错误");
}
private void writerToken(HttpServletRequest request, HttpServletResponse response, AbstractAuthenticationToken token
, String badCredenbtialsMsg) throws IOException {
try {
final String[] clientInfos = AuthUtils.extractClient(request);
String clientId = clientInfos[0];
String clientSecret = clientInfos[1];
ClientDetails clientDetails = getClient(clientId, clientSecret);
//保存租户id
TenantContextHolder.setTenant(clientId);
TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "customer");
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
Authentication authentication = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken oAuth2AccessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
oAuth2Authentication.setAuthenticated(true);
TenantContextHolder.clear();
ResponseUtil.responseSucceed(objectMapper, response, oAuth2AccessToken);
} catch (BadCredentialsException | InternalAuthenticationServiceException e) {
exceptionHandler(response, badCredenbtialsMsg);
} catch (Exception e) {
exceptionHandler(response, e);
}
}
private void exceptionHandler(HttpServletResponse response, Exception e) throws IOException {
log.error("exceptionHandler-error:", e);
exceptionHandler(response, e.getMessage());
}
private void exceptionHandler(HttpServletResponse response, String msg) throws IOException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
ResponseUtil.responseFailed(objectMapper, response, msg);
}
private ClientDetails getClient(String clientId, String clientSecret) {
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("clientId对应的信息不存在");
} else if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
throw new UnapprovedClientAuthenticationException("clientSecret不匹配");
}
return clientDetails;
}
}
package com.central.oauth.filter;
import com.central.common.constant.SecurityConstants;
import com.central.common.utils.ResponseUtil;
import com.central.oauth.exception.ValidateCodeException;
import com.central.oauth.service.IValidateCodeService;
import com.central.oauth2.common.properties.SecurityProperties;
import com.central.oauth2.common.util.AuthUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author zlt
* @date 2018/11/21
*/
@Slf4j
@Component("validateCodeFilter")
public class ValidateCodeFilter extends OncePerRequestFilter {
@Autowired
private IValidateCodeService validateCodeService;
@Autowired
private SecurityProperties securityProperties;
@Resource
private ObjectMapper objectMapper;
/**
* 验证请求url与配置的url是否匹配的工具类
*/
private AntPathMatcher pathMatcher = new AntPathMatcher();
/**
* 返回true代表不执行过滤器,false代表执行
*/
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
//登录提交的时候验证验证码
if (pathMatcher.match(SecurityConstants.PASSWORD_LOGIN_PRO_URL, request.getRequestURI())) {
//判断是否有不验证验证码的client
if (securityProperties.getCode().getIgnoreClientCode().length > 0) {
try {
final String[] clientInfos = AuthUtils.extractClient(request);
String clientId = clientInfos[0];
for (String client : securityProperties.getCode().getIgnoreClientCode()) {
if (client.equals(clientId)) {
return true;
}
}
} catch (Exception e) {
log.error("解析client信息失败", e);
}
}
return false;
}
return true;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
validateCodeService.validate(request);
} catch (ValidateCodeException e) {
ResponseUtil.responseWriter(objectMapper, response, e.getMessage(), HttpStatus.BAD_REQUEST.value());
return;
}
chain.doFilter(request, response);
}
}
\ No newline at end of file
package com.central.oauth.granter;
import com.central.oauth2.common.token.MobileAuthenticationToken;
import com.central.oauth2.common.token.OpenIdAuthenticationToken;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* openId授权模式
*
* @author zlt
* @date 2020/7/11
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class MobilePwdGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "mobile_password";
private final AuthenticationManager authenticationManager;
public MobilePwdGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices
, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.authenticationManager = authenticationManager;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
String mobile = parameters.get("mobile");
String password = parameters.get("password");
// Protect from downstream leaks of password
parameters.remove("password");
Authentication userAuth = new MobileAuthenticationToken(mobile, password);
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
userAuth = authenticationManager.authenticate(userAuth);
if (userAuth == null || !userAuth.isAuthenticated()) {
throw new InvalidGrantException("Could not authenticate mobile: " + mobile);
}
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOAuth2Request, userAuth);
}
}
package com.central.oauth.granter;
import com.central.oauth.service.IValidateCodeService;
import com.central.oauth2.common.token.OpenIdAuthenticationToken;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* openId授权模式
*
* @author zlt
* @date 2020/7/11
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class OpenIdGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "openId";
private final AuthenticationManager authenticationManager;
public OpenIdGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices
, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.authenticationManager = authenticationManager;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
String openId = parameters.get("openId");
Authentication userAuth = new OpenIdAuthenticationToken(openId);
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
userAuth = authenticationManager.authenticate(userAuth);
if (userAuth == null || !userAuth.isAuthenticated()) {
throw new InvalidGrantException("Could not authenticate openId: " + openId);
}
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOAuth2Request, userAuth);
}
}
package com.central.oauth.granter;
import com.central.oauth.service.IValidateCodeService;
import org.springframework.security.authentication.*;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* password添加图像验证码授权模式
*
* @author zlt
* @date 2020/7/11
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class PwdImgCodeGranter extends ResourceOwnerPasswordTokenGranter {
private static final String GRANT_TYPE = "password_code";
private final IValidateCodeService validateCodeService;
public PwdImgCodeGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices
, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, IValidateCodeService validateCodeService) {
super(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.validateCodeService = validateCodeService;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
String deviceId = parameters.get("deviceId");
String validCode = parameters.get("validCode");
//校验图形验证码
validateCodeService.validate(deviceId, validCode);
return super.getOAuth2Authentication(client, tokenRequest);
}
}
......@@ -7,6 +7,9 @@ import javax.servlet.http.HttpServletRequest;
/**
* @author zlt
* @date 2018/12/10
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public interface IValidateCodeService {
/**
......@@ -33,5 +36,5 @@ public interface IValidateCodeService {
/**
* 验证验证码
*/
void validate(HttpServletRequest request);
void validate(String deviceId, String validCode);
}
......@@ -12,15 +12,15 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @author zlt
* @date 2018/12/10
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
@Slf4j
@Service
......@@ -95,19 +95,12 @@ public class ValidateCodeServiceImpl implements IValidateCodeService {
* 验证验证码
*/
@Override
public void validate(HttpServletRequest request) {
String deviceId = request.getParameter("deviceId");
public void validate(String deviceId, String validCode) {
if (StringUtils.isBlank(deviceId)) {
throw new ValidateCodeException("请在请求参数中携带deviceId参数");
}
String code = this.getCode(deviceId);
String codeInRequest;
try {
codeInRequest = ServletRequestUtils.getStringParameter(request, "validCode");
} catch (ServletRequestBindingException e) {
throw new ValidateCodeException("获取验证码的值失败");
}
if (StringUtils.isBlank(codeInRequest)) {
if (StringUtils.isBlank(validCode)) {
throw new ValidateCodeException("请填写验证码");
}
......@@ -115,7 +108,7 @@ public class ValidateCodeServiceImpl implements IValidateCodeService {
throw new ValidateCodeException("验证码不存在或已过期");
}
if (!StringUtils.equals(code, codeInRequest.toLowerCase())) {
if (!StringUtils.equals(code, validCode.toLowerCase())) {
throw new ValidateCodeException("验证码不正确");
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册