(4)SpringBoot集成SpringSecurity前后分离解决方案-下

本编主要是实现如果结合JWT实现登录和访问时的验证

目录

1、实现登录

1.1 AjaxResponseBody

1.2 AjaxAuthenticationSuccessHandler

2、访问拦截认证

2.1、自定义 JwtAuthenticationTokenFilter


1、实现登录

1.1 AjaxResponseBody

加入jwtToken属性

public class AjaxResponseBody implements Serializable{

    private String status;
    private String msg;
    private Object result;
    //加入jwt属性
    private String jwtToken;

1.2 AjaxAuthenticationSuccessHandler

 登录认证成功之后,在客户端的发会信息中加入jwt token

@Component
public class AjaxAuthenticationSuccessHandler  implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        responseBody.setStatus("200");
        responseBody.setMsg("Login Success! 登录成功");
        
        //登录成功加入jwt token
        //SelfUserDetails是在UserDetailsService中产生的,这一点有点类似shiro的用户对象
        SelfUserDetails userDetails = (SelfUserDetails) authentication.getPrincipal();
        String jwtToken = JwtTokenUtil.generateToken(userDetails.getUsername(), 300, "_secret");
        responseBody.setJwtToken(jwtToken);

        httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
    }
}

2、访问拦截认证

2.1、自定义 JwtAuthenticationTokenFilter

package com.grsoft.security.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Description: 登录前做token的校验
 * @author: :  Steven
 * @Date: 2020/2/14 17:41
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    //注意1.普通的doFilter,实现存储“已过滤”的请求属性,如果属性已经存在,则继续进行而不再过滤。
    //    2.doFilterInternal和doFilter相同功能,但保证在单个请求线程中每个请求只调用一次。
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

        // 获得请求的URL
        String url = request.getRequestURL().toString();
        if (url.endsWith("/login")) {
            chain.doFilter(request, response);

        } else {
            //此处省略JWT校验代码
            if (Jwt校验通过) {
                chain.doFilter(request, response);
            } else {
                response.sendRedirect("/login");
            }
        }
    }
}

2.2 WebSecurityConfigurerAdapter

在WebSecurityConfigurerAdapter中加入自定义的JwtAuthenticationTokenFilter 

 @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()

                .httpBasic().authenticationEntryPoint(authenticationEntryPoint)

                .and()
                .authorizeRequests()

                .anyRequest()
                .authenticated()// 其他 url 需要身份认证

                .and()
                .formLogin()  //开启登录
//                .loginPage("/myLogin.html")// 自定义登录页面
//                .loginProcessingUrl("/login.do")// 自定义登录controller
                .successHandler(authenticationSuccessHandler) // 登录成功
                .failureHandler(authenticationFailureHandler) // 登录失败
                .permitAll()

                .and()
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler)
                .permitAll();

        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
        //加入过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }
发布了116 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/allensandy/article/details/104316711