Spring Security oauth2 用户名密码登录

image.png

思路:在登录成功后的AuthenticationSuccessHandler获取token,传给前端。

@Component("fuiouAuthenticationSuccessHandler")
@Slf4j
public class FuiouAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private ClientDetailsService clientDetailsService;
    
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

        //authentication 封装了认证信息
        
        // 1、获取请求中的clientId和clientSecret
        String header = request.getHeader("Authorization");
        if (header == null || !header.startsWith("Basic ")) {
            throw new UnapprovedClientAuthenticationException("请求头中无client信息");
        }
        String[] tokens = extractAndDecodeHeader(header, request);
        String clientId=tokens[0];
        String clientSecret=tokens[1];
        
        // 2、获取clientDetails
        ClientDetails clientDetails=clientDetailsService.loadClientByClientId(clientId);
        if(clientDetails==null) {
            throw new UnapprovedClientAuthenticationException("clientId对应的配置信息不存在"+clientId);
        }else if(!StringUtils.equals(clientSecret, clientDetails.getClientSecret())) {
            throw new UnapprovedClientAuthenticationException("clientSecret不匹配"+clientId);
        }
        TokenRequest tokenRequest=new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");
        OAuth2Request oAuth2Request=tokenRequest.createOAuth2Request(clientDetails);
        OAuth2Authentication oAuth2Authentication=new OAuth2Authentication(oAuth2Request, authentication);
        OAuth2AccessToken oAuth2AccessToken=authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(oAuth2AccessToken));
    }

    private String[] extractAndDecodeHeader(String header, HttpServletRequest request)
            throws IOException {

        byte[] base64Token = header.substring(6).getBytes("UTF-8");
        byte[] decoded;
        try {
            decoded = Base64.decode(base64Token);
        }
        catch (IllegalArgumentException e) {
            throw new BadCredentialsException(
                    "Failed to decode basic authentication token");
        }

        String token = new String(decoded, "UTF-8");

        int delim = token.indexOf(":");

        if (delim == -1) {
            throw new BadCredentialsException("Invalid basic authentication token");
        }
        return new String[] { token.substring(0, delim), token.substring(delim + 1) };
    }
}
@Configuration
@EnableResourceServer
public class FuiouResourceServerConfig extends ResourceServerConfigurerAdapter{
    
    @Autowired
    private AuthenticationSuccessHandler fuiouAuthenticationSuccessHandler;
    
    @Autowired
    private AuthenticationFailureHandler fuiouAuthenticationFailureHandler;
    
    @Autowired
    private SecurityProperties securityProperties;
    
    @Autowired
    private SpringSocialConfigurer fuiouSocialSecurityConfig;
    
    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
    
    @Override
    public void configure(HttpSecurity http) throws Exception {

//      ValidateCodeFilter filter=new ValidateCodeFilter();
//      filter.setAuthenticationFailureHandler(fuiouAuthenticationFailureHandler);
//      filter.setSecurityProperties(securityProperties);
//      filter.afterPropertiesSet();
        
        SmsCodeFilter smsCodefilter=new SmsCodeFilter();
        smsCodefilter.setAuthenticationFailureHandler(fuiouAuthenticationFailureHandler);
        smsCodefilter.setSecurityProperties(securityProperties);
        smsCodefilter.afterPropertiesSet();
        
        http
            .apply(fuiouSocialSecurityConfig)
            .and()
            .addFilterBefore(smsCodefilter, UsernamePasswordAuthenticationFilter.class)
            //.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
            .formLogin()
            .loginPage("/authentication/requrie")//登录页面
            .loginProcessingUrl("/authentication/form")
            .successHandler(fuiouAuthenticationSuccessHandler)
            .failureHandler(fuiouAuthenticationFailureHandler)
            .and()
            .authorizeRequests()//请求授权
            .antMatchers("/authentication/requrie",
                        securityProperties.getBrowser().getLoginPage(),
                        "/code/*",securityProperties.getBrowser().getSiginUpUrl(),
                        "/user/regist","/session/invalid","/index.html",
                        "/fuiou-logOut.html","/signOut")
            .permitAll()//该url不需要身份认证
            .anyRequest()       //任何请求
            .authenticated()//身份认证
            .and()
            .csrf().disable()//关闭csrf防护
            .apply(smsCodeAuthenticationSecurityConfig)
            ;
    
    }
}

这样登录后就能得到token


image.png
image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。