4 spring-security

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 这些接口 对于认证中心来说无需授权
     */
    protected static final String[] PERMIT_ALL_URL = {"/oauth/**", "/user/**", "/actuator/**", "/error", "/open/api"};
    @Resource
    private AuthenticationProvider myAuthenticationProvider;
    @Resource
    private AuthCommonConfig authCommonConfig;

    @Value("${spring.profiles.active}")
    private String profile;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and().csrf().disable()
                .authorizeRequests()
                //处理跨域请求中的Preflight请求
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .antMatchers(PERMIT_ALL_URL)
                .permitAll()
                .and()
                .formLogin()
//                .loginPage(authCommonConfig.getLoginPage())
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(authenticationSuccessHandler())
                .failureHandler(authenticationFailureHandler())
                .and().logout()
                .logoutSuccessHandler(logoutSuccessHandler())
                .deleteCookies("SESSIONID")
//                .and().httpBasic()
        ;
    }


    public static void main(String[] args) {
        System.out.println(new BCryptPasswordEncoder().encode("123456"));
        System.out.println(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456"));
        System.out.println(PasswordEncoderFactories.createDelegatingPasswordEncoder().matches("123456", "{bcrypt}$2a$10$tuMR8ca2nM5miqc6cNHlxOjQrtOIDPVCpTt69jwTOcsEgIEBYFfjm"));
    }

    /**
     * 登录成功处理器
     */
    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        return (httpServletRequest, httpServletResponse, authentication) -> {
//            RequestCache requestCache = new HttpSessionRequestCache();
//            SavedRequest savedRequest = requestCache.getRequest(httpServletRequest, httpServletResponse);
//            String targetUrl = savedRequest.getRedirectUrl();
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            String state = httpServletRequest.getParameter("state");
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(authCommonConfig.getAuthDomain() +
                    "/auth/oauth/authorize")
                    .queryParam("response_type", "code")
                    .queryParam("state", httpServletRequest.getParameter("state"))
                    .queryParam("client_id", httpServletRequest.getParameter("client_id"))
                    .queryParam("redirect_uri", httpServletRequest.getParameter("redirect_uri"))
                    .queryParam("scope", httpServletRequest.getParameter("scope"));
            String redirectUrl = builder.encode().toUriString();
            if (Objects.equals("dev", profile)) {
                httpServletResponse.sendRedirect(redirectUrl);
                return;
            }
            //如果不确定,则默认跳回用户中心
            httpServletResponse.getWriter().write(objectMapper.writeValueAsString(ResultModel.success(
                    redirectUrl
            )));
            return;
        };
    }

    /**
     * 登出成功处理器
     */
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler() {
        return (httpServletRequest, httpServletResponse, authentication) -> {
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            httpServletResponse.getWriter().write(objectMapper.writeValueAsString(ResultModel.success()));
        };
    }

    /**
     * 常规登录失败处理器
     */
    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return (httpServletRequest, httpServletResponse, e) -> {
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            String message = "登录失败";
            if (e instanceof UsernameNotFoundException) {
                message = e.getMessage();
            }
            if (e instanceof BadCredentialsException) {
                message = e.getMessage();
            }
            if (e instanceof AccountExpiredException) {
                message = e.getMessage();
            }

            httpServletResponse.getWriter().write(objectMapper.writeValueAsString(ResultModel.fail(
                    String.valueOf(HttpStatus.UNAUTHORIZED.value()), message)
            ));
        };
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(this.myAuthenticationProvider);
//        auth.userDetailsService(oauthAccountUserDetailsService).passwordEncoder(passwordEncoder());
        auth.eraseCredentials(true);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

//    @Bean
//    public UrlBasedViewResolver UrlBasedViewResolver() throws Exception {
//        UrlBasedViewResolver v = new UrlBasedViewResolver();
//        v.setRedirectHttp10Compatible(false);
//        v.setViewClass(RedirectView.class);
//        return v;
//    }
//    @Bean
//    public DefaultRedirectStrategy DefaultRedirectStrategy() throws Exception {
//        DefaultRedirectStrategy v = new DefaultRedirectStrategy();
//        v.setContextRelative(true);
//        return v;
//    }
}

自己实现账号密码验证规则

@Component
@Slf4j
public class MyAuthenticationProvider implements AuthenticationProvider {
    @Resource
    private RestTemplate restTemplate;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();
        String clientId = getClientIdByRequest();
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("username", username);
        paramMap.put("password", password);
        paramMap.put("clientId", clientId);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://uc-user-service/user/v1/rpc/user/loadUserByUsername");
        paramMap.forEach(builder::queryParam);
        String result = restTemplate.getForObject(builder.encode().toUriString(),
                String.class, paramMap);
        log.info("用户登录:{}->{}", username, result);
        ResultModel<LoginUserVO> resultModel = JsonUtils.string2Obj(result, new TypeReference<ResultModel<LoginUserVO>>() {
        });
        // 根据用户名获取用户信息
        if (!resultModel.isSuccess()) {
            throw new BadCredentialsException(resultModel.getMessage());
        } else {
            LoginUserVO account = resultModel.getData();
            return new UsernamePasswordAuthenticationToken(
                    new OauthAccountUserDetails(account, new ArrayList<>()),
                    authentication.getCredentials(), emptyList());
        }
    }

    public String getClientIdByRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) throw new UnsupportedOperationException();
        HttpServletRequest request = attributes.getRequest();
        String clientId = request.getParameter("client_id");
        if (StringUtils.isNotEmpty(clientId)) {
            return clientId;
        }
        String auth = request.getHeader("Authorization");
        auth = StringUtils.substringAfter(auth, "Basic ");
        return new String(Base64.getDecoder().decode(auth)).split(":")[0];
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值