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

(八) OAuth 2.0 认证成功,认证失败,退出成功

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

(八) OAuth 2.0 认证成功,认证失败,退出成功

认证成功

监听AuthenticationSuccessEvent,注意在刷新令牌,校验令牌,登录密码校验成功都会发布这个事件,所以我们需要在监听器里面做一些排查判断。successHandler是自定义业务逻辑类。

public class AuthenticationSuccessEventListener implements ApplicationListener {

    @Autowired(required = false)
    private AuthenticationSuccessHandler successHandler;

    @Override
    public void onApplicationEvent(AuthenticationSuccessEvent event) {
        Authentication authentication = (Authentication) event.getSource();

        // successHandler不为空并且已经是认证用户,从请求上下文中拿到请求属性
        if (successHandler != null && isUserAuthentication(authentication)) {

            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = requestAttributes.getRequest();
            HttpServletResponse response = requestAttributes.getResponse();

            // 调用自定义业务实现
            successHandler.handle(authentication, request, response);
        }
    }

    private boolean isUserAuthentication(Authentication authentication) {
        if (authentication.getPrincipal() instanceof SecurityUser) {
            return true;
        }
        return CollUtil.isNotEmpty(authentication.getAuthorities());
    }

}
认证失败

监听AuthenticationFailureBadCredentialsEvent,注意在刷新令牌,校验令牌,登录密码校验成功都会发布这个事件,所以我们需要在监听器里面做一些排查判断。successHandler是自定义业务逻辑类。

public class AuthenticationFailureEventListener implements ApplicationListener {

    @Autowired(required = false)
    private AuthenticationFailureHandler failureHandler;

    
    @Override
    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {


        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();

        AuthenticationException authenticationException = event.getException();
        Authentication authentication = (Authentication) event.getSource();

        // 调用自定义业务实现
        if (failureHandler != null) {
            failureHandler.handle(authenticationException, authentication, request, response);
        }
    }

    private boolean isUserAuthentication(Authentication authentication) {
        if (authentication.getPrincipal() instanceof SecurityUser) {
            return true;
        }
        return CollUtil.isNotEmpty(authentication.getAuthorities());
    }

}
退出成功

Spring security oauth2.0是没有退出接口的

@RestController
@AllArgsConstructor
@RequestMapping("/token")
public class CustomTokenEndpoint {

    private final TokenStore tokenStore;

    
    @DeleteMapping("/logout")
    public R logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {

        if (StrUtil.isBlank(authHeader)) {
            return R.ok(Boolean.FALSE, "退出失败,token 为空");
        }

        String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, "").trim();

        OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
        if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
            return R.ok(Boolean.TRUE, "退出失败,token 无效");
        }
        OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);
        // 清空用户信息
        // 清空access token
        tokenStore.removeAccessToken(accessToken);
        // 清空 refresh token
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        tokenStore.removeRefreshToken(refreshToken);
        // 发送退出成功事件
        SpringContextHolder.publishEvent(new LogoutSuccessEvent(auth2Authentication));
        return R.ok();
    }

    
    @GetMapping(value = "/authentication")
    public String info() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!authentication.isAuthenticated()) {
            return null;
        }
        Object principal = authentication.getPrincipal();
        String username = null;
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
        } else {
            username = principal.toString();
        }
        return username;
    }
}

event

public class LogoutSuccessEvent extends AbstractAuthenticationEvent {

    public LogoutSuccessEvent(Authentication authentication) {
        super(authentication);
    }

}
@Slf4j
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

    private static ApplicationContext applicationContext = null;

    
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }

    
    @SuppressWarnings("unchecked")
    public static  T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }

    
    public static  T getBean(Class requiredType) {
        return applicationContext.getBean(requiredType);
    }

    
    public static void clearHolder() {
        if (log.isDebugEnabled()) {
            log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
        }
        applicationContext = null;
    }

    
    public static void publishEvent(ApplicationEvent event) {
        if (applicationContext == null) {
            return;
        }
        applicationContext.publishEvent(event);
    }

    
    @Override
    public void destroy() {
        SpringContextHolder.clearHolder();
    }

}

监听器

@Slf4j
public class AuthenticationLogoutSuccessEventListener implements ApplicationListener {

    @Autowired(required = false)
    private AuthenticationLogoutHandler logoutHandler;

    
    @Override
    public void onApplicationEvent(LogoutSuccessEvent event) {
        OAuth2Authentication authentication = (OAuth2Authentication) event.getSource();

        // successHandler不为空 并且 已经是认证用户 。从请求上下文中拿到请求属性
        if (logoutHandler != null && isUserAuthentication(authentication)) {

            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = requestAttributes.getRequest();
            HttpServletResponse response = requestAttributes.getResponse();

            // 调用自定义业务实现
            logoutHandler.handle(authentication, request, response);
        }
    }

    private boolean isUserAuthentication(Authentication authentication) {
        if (authentication.getPrincipal() instanceof SecurityUser) {
            return true;
        }
        return CollUtil.isNotEmpty(authentication.getAuthorities());
    }
}

最后记得加上@Component注解放入Spring容器中

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

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

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