栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Security Oauth2 自定义授权类型实现短信验证码登陆

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Security Oauth2 自定义授权类型实现短信验证码登陆

参考:https://blog.csdn.net/weixin_42271016/article/details/104212326
参考:https://segmentfault.com/a/1190000019894976?utm_source=tag-newest

创建自定义抽象令牌授予者
import org.springframework.security.core.userdetails.UserDetails;
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 org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

import java.util.Map;

public abstract class AbstractCustomTokenGranter extends AbstractTokenGranter {

    private final OAuth2RequestFactory requestFactory;

    protected AbstractCustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
        super(tokenServices, clientDetailsService, requestFactory, grantType);
        this.requestFactory = requestFactory;
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map parameters = tokenRequest.getRequestParameters();
        UserDetails userDetails = getUserDetails(parameters);
        if (userDetails == null) {
            throw new InvalidGrantException("Unable to get user information");
        }
        OAuth2Request storedOAuth2Request = this.requestFactory.createOAuth2Request(client, tokenRequest);
        PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        authentication.setDetails(userDetails);
        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(storedOAuth2Request, authentication);
        return oAuth2Authentication;
    }

    protected abstract UserDetails getUserDetails(Map parameters);
短信验证码登录令牌授予者
import com.freedom.security.auth.config.custom.CustomUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.Map;

public class PhoneSmsCustomTokenGranter extends AbstractCustomTokenGranter {

    private static final String GRANT_TYPE = "phone_sms";

    private CustomUserDetailsService userDetailsService;

    public PhoneSmsCustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, UserDetailsService userDetailsService) {
        super(tokenServices, clientDetailsService, requestFactory,GRANT_TYPE);
        this.userDetailsService = (CustomUserDetailsService)userDetailsService;
    }

    @Override
    protected UserDetails getUserDetails(Map parameters) {
        String phone = parameters.get("phone");
        String smsCode = parameters.get("sms_code");
        return userDetailsService.loadUserByPhoneAndSmsCode(phone, smsCode);
    }
}
自定义UserDetailsService接口
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

public interface CustomUserDetailsService extends UserDetailsService {
    
    UserDetails loadUserByPhoneAndSmsCode(String phone, String smsCode);
}
实现CustomUserDetailsService
@Component
public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {

    @Autowired
    private IUserService iUserService;

    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 编辑验证账号密码逻辑并返回UserDetails信息
        return null;
    }

    @Override
    public UserDetails loadUserByPhoneAndSmsCode(String phone, String captcha) {
        // 编辑短信验证逻辑并返回UserDetails信息
        return null;
    }
}
修改授权服务器
@Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        List tokenGranters = getTokenGranters(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory());
        
        // 添加自定义令牌授权策略
        List tokenGranters = getDefaultTokenGranters(
                endpoints.getTokenServices(),
                endpoints.getClientDetailsService(),
                endpoints.getAuthorizationCodeServices(),
                endpoints.getOAuth2RequestFactory(),
                this.authenticationManager,
                userDetailsService);

        endpoints
                .authenticationManager(this.authenticationManager)
                // 指定令牌授权者
                .tokenGranter(new CompositeTokenGranter(tokenGranters))

    }

	
    private List getDefaultTokenGranters(AuthorizationServerTokenServices tokenServices,
                                                       ClientDetailsService clientDetailsService,
                                                       AuthorizationCodeServices authorizationCodeServices,
                                                       OAuth2RequestFactory requestFactory,
                                                       AuthenticationManager authenticationManager,
                                                       UserDetailsService userDetailsService) {
        List tokenGranters = new ArrayList();
        tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetailsService,
                requestFactory));
        tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetailsService, requestFactory));
        ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetailsService, requestFactory);
        tokenGranters.add(implicit);
        tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, requestFactory));
        if (authenticationManager != null) {
            tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
                    clientDetailsService, requestFactory));
        }
        // 添加自定义短信令牌授权者
        tokenGranters.add(new PhoneSmsCustomTokenGranter(tokenServices, clientDetailsService, requestFactory, userDetailsService));
        return tokenGranters;
    }

主要是这里追加自定义的令牌策略,其他策略维持源码不变

// 添加自定义短信令牌授权者
        tokenGranters.add(new PhoneSmsCustomTokenGranter(tokenServices, clientDetailsService, requestFactory, userDetailsService));
        return tokenGranters;

经过以上调整添加了新的grant类型为 "phone_sms",并且新增入参"phone"、 "sms_code"两个参数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324927.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号