package cn.gistack.auth.granter; import cn.gistack.auth.utils.TokenUtil; import cn.gistack.common.cache.CacheNames; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.tool.utils.StringUtil; import org.springframework.security.authentication.*; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException; 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; /** * 微信授权验证TokenGranter * * @author Guoshilong */ public class OAuthTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "oauth"; private final AuthenticationManager authenticationManager; private BladeRedis bladeRedis; public OAuthTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, BladeRedis bladeRedis) { this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); this.bladeRedis = bladeRedis; } protected OAuthTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { super(tokenServices, clientDetailsService, requestFactory, grantType); this.authenticationManager = authenticationManager; } @Override protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { Map parameters = new LinkedHashMap(tokenRequest.getRequestParameters()); String phone = parameters.get("username"); String code = parameters.get("password"); // 获取oauth key String redisCode = bladeRedis.get(CacheNames.OAUTH_KEY + code); // key验证 if (code == null || !StringUtil.equalsIgnoreCase(redisCode, code)) { throw new UserDeniedAuthorizationException(TokenUtil.CAPTCHA_NOT_CORRECT); } // 通过手机号查询用户 Authentication userAuth = new UsernamePasswordAuthenticationToken(phone, code); ((AbstractAuthenticationToken) userAuth).setDetails(parameters); try { userAuth = authenticationManager.authenticate(userAuth); } catch (AccountStatusException | BadCredentialsException ase) { //covers expired, locked, disabled cases (mentioned in section 5.2, draft 31) throw new InvalidGrantException(ase.getMessage()); } // If the username/password are wrong the spec says we should send 400/invalid grant if (userAuth == null || !userAuth.isAuthenticated()) { throw new InvalidGrantException("Could not authenticate user: " + phone); } OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest); return new OAuth2Authentication(storedOAuth2Request, userAuth); } }