springboot项目整合springSecurity框架流程

1.导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.编写配置类

在config文件夹下创建MySpringSecurityConfiguration作为本项目对于SpringSecurity框架的配置类, 并添加@Configuration注解。

继承框架WebSecurityConfigurerAdapter并重写两个configure方法。(以绑定自定义的认证和过滤器)        

@Autowired
UserDetailsService mySecurityService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(mySecurityService) // 绑定自定义的认证Service
            .passwordEncoder(new BCryptPasswordEncoder()); // 绑定密码处理器
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/doc.html", "/doc.html/**", "/webjars/**", "/v2/**", "/swagger-resources",
                    "/swagger-resources/**", "/swagger-ui.html", "/swagger-ui.html/**").permitAll()
            .anyRequest().authenticated()
            .and()
            // 设置跨域的处理
            .cors().configurationSource(corsConfigurationSource())
            .and()
            .addFilter(new TokenLoginFilter(super.authenticationManager())) // 绑定认证的接口(将步骤三定义的登录过滤器扔进来)
            .addFilter(new TokenVerifyFilter(super.authenticationManager())) // 绑定校验的接口(将步骤四定义的token校验过滤器扔进来)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

自定义认证业务类继承SpringSecurity框架的UserDetailsService并重写loadUserByUsername(此方法完成账号的校验)

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    // 1.需要根据账号查询
    List<SysUser> list = sysUserService.queryByUserName(username);
    if(list != null && list.size() == 1){
        // 账号是存在的
        SysUser sysUser = list.get(0);
        // 根据当前登录的账号查询到关联的角色信息
        List<SysRole> sysRoles = sysRoleService.queryByUserId(sysUser.getUserId());
        List<GrantedAuthority> listRole = new ArrayList<>();
        if(sysRoles != null && sysRoles.size() > 0){
            for (SysRole sysRole : sysRoles) {
                //绑定当前用户所关联的角色
                listRole.add(new SimpleGrantedAuthority(sysRole.getRoleName()));
            }
        }
        // 密码模拟的是就数据库查询出来
        return new User(sysUser.getUsername(),sysUser.getPassword(),listRole);
    }
    return null;
}
3.重写登录过滤器

在filter文件夹中建过滤器类,例:UserNamePassWordLoginFilter,继承SpringSecurity框架的UsernamePasswordAuthenticationFilter

private AuthenticationManager authenticationManager;

public UsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager){
    this.authenticationManager = authenticationManager;
}

/**
 * 具体认证的方法
 * @param request
 * @param response
 * @return
 * @throws AuthenticationException
 */
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    SysUser sysUser = null;
    // 前后端分离的项目中我们提交的数据是JSON字符串。不是表单提交的
    try {
        String loginInfo = getRequestJSON(request);
        sysUser = JSON.parseObject(loginInfo, SysUser.class);
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(sysUser.getUsername(),sysUser.getPassword());
        return authenticationManager.authenticate(authenticationToken);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

private String getRequestJSON(HttpServletRequest request) throws IOException {
    BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String inputStr = null;
    while((inputStr = streamReader.readLine() ) != null){
        sb.append(inputStr);
    }
    return sb.toString();
}

/**
 * 登录成功的方法
 * @param request
 * @param response
 * @param chain
 * @param authResult
 * @throws IOException
 * @throws ServletException
 */
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response
        , FilterChain chain, Authentication authResult) throws IOException, ServletException {
    // 生成Token信息
    Map<String,String> map = new HashMap<>();
    map.put("username",authResult.getName());
    // 生成对应的Token信息
    String token = JWTUtils.getToken(map);
    // 需要把生成的Token信息响应给客户端
    response.addHeader("Authorization", SystemConstant.SYS_TOKEN_PREFIX +token);
    response.addHeader("Access-Control-Expose-Headers","Authorization");
    response.setContentType("application/json;charset=utf-8");
    response.setStatus(HttpServletResponse.SC_OK);
    PrintWriter writer = response.getWriter();
    Map<String,Object> resultMap = new HashMap<>();
    resultMap.put("code", HttpServletResponse.SC_OK);
    resultMap.put("msg","认证通过");
    writer.write(JSON.toJSONString(resultMap));
    writer.flush();
    writer.close();
}

/**
 * 登录失败的方法
 * @param request
 * @param response
 * @param failed
 * @throws IOException
 * @throws ServletException
 */
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
    response.setContentType("application/json;charset=utf-8");

    response.setStatus(HttpServletResponse.SC_OK);
    PrintWriter writer = response.getWriter();
    Map<String,Object> resultMap = new HashMap<>();
    resultMap.put("code", HttpServletResponse.SC_UNAUTHORIZED);
    resultMap.put("msg","用户名或密码错误!");
    writer.write(JSON.toJSONString(resultMap));
    writer.flush();
    writer.close();
}
4.校验提交的Token

在filter文件夹中建过滤器类,例:TokenBasicAuthenticationFilter,继承SpringSecurity框架的BasicAuthenticationFilter

private AuthenticationManager authenticationManager;
public TokenBasicAuthenticationFilter(AuthenticationManager authenticationManager) {
    super(authenticationManager);
}

/**
 * 校验提交的Token是否合法的方法
 * @param request
 * @param response
 * @param chain
 * @throws IOException
 * @throws ServletException
 */
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("--->"+request.getRequestURI());
    // 获取请求携带的Token信息
    String header = request.getHeader("Authorization");
    String requestURI = request.getRequestURI();
    String contextPath = request.getContextPath();
    String path = requestURI.replace(contextPath,"");
    List<String> msgs = Arrays.asList("/doc.html","/webjars","/v2","/v3","/favicon.ico","swagger-resources");
    for (String p : msgs) {
        if(path.contains(p)){
            // 放过请求
            chain.doFilter(request,response);
            return ;
        }
    }

    System.out.println("request.getContextPath() = " + request.getContextPath());
    if(header != null && header.startsWith(SystemConstant.SYS_TOKEN_PREFIX)){
        // 传递了Token信息。同时有我们添加的对应的前缀
        // 1.获取到正常的token
        String token = header.replace(SystemConstant.SYS_TOKEN_PREFIX, "");
        // 2.校验token信息是否合法
        DecodedJWT verify = JWTUtils.verify(token);
        if(verify == null){
            responseLogin(response);
        }
        // 走到这儿说明是正常
        // 获取当前登录的账号信息
        String userName = verify.getClaim("username").asString();
        // 放过请求 查找权限
        List<GrantedAuthority> list = authenticationManager.getAuthentication(userName);
        // 根据账号获取相关的权限
        UsernamePasswordAuthenticationToken authenticationToken
                = new UsernamePasswordAuthenticationToken(userName,"",list);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        // 放过请求
        chain.doFilter(request,response);

    }else{
        // 没有携带Token或者是非法的请求
        responseLogin(response);
    }
}

private void responseLogin(HttpServletResponse response) throws IOException {
    // 说明校验失败 -- 给用户提示请先登录
    response.setContentType("application/json;charset=utf-8");
    response.setStatus(HttpServletResponse.SC_OK);
    PrintWriter writer = response.getWriter();
    Map<String,Object> resultMap = new HashMap<>();
    resultMap.put("code", HttpServletResponse.SC_FORBIDDEN);
    resultMap.put("msg","请先登录!");
    writer.write(JSON.toJSONString(resultMap));
    writer.flush();
    writer.close();
}

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Security 是 Spring 社区提供的一个强大的安全框架,它可以帮助我们轻松地实现认证、授权、攻击防护等功能。Spring Boot 与 Spring Security 的整合非常简单,我们只需要在项目中添加相应的依赖,然后进行必要的配置即可。 下面是一个简单的 Spring Boot 整合 Spring Security 的示例: 1. 添加 Spring Security 依赖 在项目的 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置 Spring Security 在 Spring Boot 项目中,可以通过在 application.properties 或 application.yml 文件中进行配置。以下是一个简单的配置示例: ```yml spring: security: user: name: admin password: admin123 # 关闭CSRF保护 csrf: enabled: false ``` 在这个示例中,我们配置了一个用户名为 admin,密码为 admin123 的用户,并且关闭了 CSRF 保护。 3. 编写控制器 接下来,我们需要编写一个简单的控制器,用于测试 Spring Security 的功能。以下是一个简单的示例: ```java @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, World!"; } } ``` 4. 运行项目 现在,我们可以启动应用程序,并在浏览器中访问 http://localhost:8080/hello 来测试 Spring Security 的功能。在访问该 URL 时,系统将会弹出一个默认的登录页面,我们可以使用之前配置的用户名和密码进行登录,然后就可以看到 "Hello, World!" 的返回值了。 以上就是一个简单的 Spring Boot 整合 Spring Security 的示例。在实际项目中,我们还需要根据具体的需求进行更加复杂的配置和实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值