【Spring Boot 集成应用】Spring Security集成整合配置使用

阅读: 评论:0

【Spring Boot 集成应用】Spring Security集成整合配置使用

【Spring Boot 集成应用】Spring Security集成整合配置使用

1. Spring Security 简介

Spring Security 是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。原名Acegi Security,最早于2003年起源于Spring社区。 2007年末正式归为Spring Framework的正式子项目,并改名为Spring Security 。此后, Spring Security有了长远发展,现已成为一款基于Spring Framework的广泛应用的安全框架,主要为应用服务提供用户认证(Authentication)和用户授权(Authorization)功能。详情可参考Spring Security 官方文档。

Spring Security 针对安全方面的两大难题, 鉴权(Authentication)和授权(Authorization)提供了灵活强大的解决方案。

  • 用户鉴权(Authentication), 是指对用户身份的鉴权, 验证某个用户是否为系统中的合法对象, 是否能够访问对应的系统资源。比如用户输入账户和密码登陆系统。
  • 用户授权(Authorization),是指授予通过认证的用户指定的系统资源操作权限, 能否执行具体某个操作。比如用户能够访问操作的菜单,能够请求的功能接口, 这些都是系统资源。

Spring Security优势:

  • 灵活性, Spring Security并不局限于Spring MVC,虽然它是基于Spring Framework实现的,但它并不依赖于Spring MVC,可以独立于MVC应用在其他Java EE框架之上。

  • 功能强大,Spring Security的安全管制并不只限制于Web请求,除此之外它还可以针对方法调用通过AOP的方式进行安全管制,甚至可以对域对象实例(Domain Object Instance)进行访问控制。

  • 安全保护, 防止伪造身份, Spring Security 会自动拦截站点所有状态变化的请求(非GET,HEAD,OPTIONS和TRACE的请求),防止跨站请求伪造(CSRF防护),即防止其他网站或是程序POST等请求本站点。

如果项目需要安全控制功能,不用自己去实现一套, 集成Spring Security专业安全框架是首选, 适用后台管理、接口资源管理、微服务统一鉴权等场景。

2. Spring Security设计处理机制

处理流程图:

  • 客户端发起一个请求,进入 Security 过滤器链。

  • 当到 LogoutFilter 的时候判断是否是登出路径,如果是登出路径则到 logoutHandler ,如果登出成功则到 logoutSuccessHandler 登出成功处理,如果登出失败则由 ExceptionTranslationFilter ;如果不是登出路径则直接进入下一个过滤器。

  • 当到 UsernamePasswordAuthenticationFilter 的时候判断是否为登录路径,如果是,则进入该过滤器进行登录操作,如果登录失败则到 AuthenticationFailureHandler 登录失败处理器处理,如果登录成功则到 AuthenticationSuccessHandler 登录成功处理器处理,如果不是登录请求则不进入该过滤器。

  • 当到 FilterSecurityInterceptor 的时候会拿到 uri ,根据 uri 去找对应的鉴权管理器,鉴权管理器做鉴权工作,鉴权成功则到 Controller 层否则到 AccessDeniedHandler 鉴权失败处理器处理。

  • 投票机制, 三种表决方式, 默认采用一票制(AffirmativeBased

    类名描述
    AffirmativeBased只要有一个投票器允许访问, 请求立刻允许放行, 不管之前存在拒绝的决定
    ConsensusBased多数票机制(允许或拒绝),多数的一方决定了AccessDecisionManager的结果。平局的投票和空票(全部弃权)的结果是可配置的
    UnanimousBased所有的投票器必须全部是允许的, 否则访问将被拒绝
3. Spring Boot 与Spring Security 集成配置

Spring Boot 与Spring Security 集成, 包含一般集成用法, 还包括自定义用户登陆页面使用, 自定义内存模式验证, 以及自定义登陆成功与失败逻辑处理。

  1. 创建工程spring-boot-security-integrate

    启动类:

    com.mirson.spring.boot.security.integrate.startup.SecurityIntegrateApplication

    @SpringBootApplication
    @ComponentScan(basePackages = {"com.mirson"})
    public class SecurityIntegrateApplication {public static void main(String[] args) {SpringApplication.run(SecurityIntegrateApplication.class, args);}
    }
  2. MAVEN依赖

    <dependencies><!-- Spring Boot Security 安全依赖组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- Spring Boot Thymeleaf 模板依赖组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- Spring Boot Web 依赖组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Spring boot freemarker 自动化配置组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency></dependencies>
    
  3. 定义一个外部访问接口

    • 创建实体

      定义一个用户实体

      com.mirson.spring.boot.security.integrate.po.User

      @Data
      public class User {/*** ID*/private Integer id;/*** 用户名称*/private String name;/*** 年龄*/private String age;/*** 省份*/private String province;/*** 创建时间*/private Date createDate;}
    • 提供Web访问接口

      提供一个获取用户信息接口

      com.mirson.spring.boot.ller.UserController

      @RestController
      @RequestMapping("/user")
      @Log4j2
      public class UserController {@GetMapping("/getUserInfo")@ResponseBodypublic User getUserInfo() {User user = new User();user.setId(0);user.setAge("21");user.setName("user1");user.setCreateDate(new Date());return user;}}
  4. 工程配置

    server:port: 22618
    spring:application:name: security-integrate# security 安全配置security:user:name: "admin"password: "admin"

    设置默认的用户名与密码为admin。

  5. 功能验证

    • 请求获取用户信息接口

      访问接口: 127.0.0.1:22618/getUserInfo

      没有鉴权的情况下, 会出现登陆界面。

    • 输入用户信息admin/admin, 再次请求获取用户信息接口

      正确输入用户信息后, 可以正常访问用户信息接口。

4. Spring Security 自定义鉴权实现
4.1 自定义登陆页面处理

Spring Security 内置会有一套登陆页面, 也可以自定修改, 这里通过freemark模板来实现自定登陆页面渲染。

# freemarker 模板配置freemarker:allow-request-override: falseallow-session-override: falsecache: truecharset: UTF-8check-template-location: truecontent-type: text/htmlenabled: trueexpose-request-attributes: falseexpose-session-attributes: falseexpose-spring-macro-helpers: trueprefer-file-system-access: truesuffix: .ftltemplate-loader-path: classpath:/templates/

增加freemark模板文件:

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="description" content=""><meta name="author" content=""><title>自定义系统登陆</title><link href="/css/bootstrap.min.css" rel="stylesheet"><link href="/css/signin.css" rel="stylesheet"></head><body><div class="container form-margin-top"><form class="form-signin" action="/user/doUserLogin" method="post"><h2 class="form-signin-heading" align="center">自定义系统登陆</h2><input type="text" name="username" class="form-control form-margin-top" placeholder="账号" required autofocus><input type="password" name="password" class="form-control" placeholder="密码" required><button class="btn btn-lg btn-primary btn-block" type="submit">sign in</button></form></div><footer><p>support by: mirson</p></footer></body>
</html>

添加CSS静态资源文件

添加JAVA CONFIG配置:

com.mirson.spring.boot.fig.SpringSecurityConfiguration

@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user/userLoginForm","/css/**").permitAll().antMatchers("/user/getUserInfo").authenticated() .and().formLogin().loginPage("/user/userLoginForm")    //自定义登录页面             .permitAll()            //允许所有人访问该路由.and().csrf().disable()                //暂时禁用csrc否则无法提交.httpBasic();}
}

重启, 访问接口: 127.0.0.1:22618/user/getUserInfo

会自动跳转到自定义的登陆页面:

4.2 自定义资源访问配置

修改com.mirson.spring.boot.fig.SpringSecurityConfiguration配置:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user/doUserLogin", "/user/userLoginForm","/css/**").permitAll().antMatchers("/user/getUserInfo").authenticated() //hasRole("ADMIN").and().formLogin().loginPage("/user/userLoginForm")    //自定义登录页面.loginProcessingUrl("/user/doUserLogin") // 自定义登陆处理地址.permitAll()            //允许所有人访问该路由.and().csrf().disable()                //暂时禁用csrc否则无法提交.httpBasic();}}

通过Spring Security 可以控制, 哪些资源需要受权限保护, 哪些可以开放访问。

  • 开放访问

    /user/userLoginForm 用户登陆页面

    /user/doUserLogin 登陆处理地址

    /css/** 静态资源文件

  • 权限保护

    /user/getUserInfo 获取用户信息接口

    可以指定Role角色权限, 不指定, 只要登陆即拥有访问权限。

loginPage指定/user/userLoginForm为自定义登陆页面;

loginProcessingUrl为登陆请求处理接口地址,可以不用对其做具体实现,Spring Security 会做默认处理。

4.3 自定义内存模式鉴权
  1. 创建鉴权用户对象:

    com.mirson.spring.boot.security.integrate.po.OAuthUser

    @Data
    public class OAuthUser extends User {public OAuthUser(String account, String password){super(account, password, true, true, true, true, Collections.EMPTY_SET);}}

    继承的是Spring Security 的User对象, 将账号和密码信息, 传递至父类构造方法。

  2. 修改SpringSecurityConfiguration配置

    增加:

    @Configuration
    @EnableWebSecurity
    public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {/*** 用户认证服务* */@Bean@Overrideprotected UserDetailsService userDetailsService() {//创建基于内存用户管理对象InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();//自定义权限Collection<GrantedAuthority> adminAuth = new ArrayList<>();adminAuth.add(new SimpleGrantedAuthority("ADMIN"));//自定义用户OAuthUser oAuthUser = new OAuthUser("admin", "admin123");ateUser(oAuthUser);return manager;}/*** 配置密码编码器, 不需加密* @return*/@Beanpublic static NoOpPasswordEncoder passwordEncoder() {return (NoOpPasswordEncoder) Instance();}...}
    

    采用内存模式管理用户对象InMemoryUserDetailsManager, 自定义认证用户名和密码, 分别为admin,admin123。 需要配置密码编码器, 可以支持自定义密码加密方式, 这里不需加密, 配置NoOpPasswordEncoder。

4.4 自定义登陆成功处理器

Spring Security 提供了接口, 登陆成功, 可以通过处理器实现自定义逻辑。
新建com.mirson.spring.boot.security.integrate.handler.SecuritySuccessHandler

@Component
@Log4j2
public class SecuritySuccessHandler extends SimpleUrlAuthenticationSuccessHandler {@Autowiredprivate ObjectMapper objectMapper;/*** 认证成功处理* @param request* @param response* @param authentication* @throws IOException* @throws ServletException*/@Overridepublic void onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication) throws IOException, ServletException {log.info("Process in SecuritySuccessHandler ==> login success.");response.setContentType("application/json;charset=UTF-8");Writer().write(objectMapper.writeValueAsString(authentication));}
}

这里通过自定义登陆成功处理器, 将登陆成功的信息返回客户端。

将处理器加入到自定义配置SpringSecurityConfiguration中:

	@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user/doUserLogin", "/user/userLoginForm","/css/**").permitAll().antMatchers("/user/getUserInfo").authenticated() //hasRole("ADMIN").and().formLogin().loginPage("/user/userLoginForm")    //自定义登录页面.loginProcessingUrl("/user/doUserLogin") // 自定义登陆处理地址.successHandler(securitySuccessHandler)  // 自定义登陆成功处理器.permitAll()            //允许所有人访问该路由.and().csrf().disable()                //暂时禁用csrc否则无法提交.httpBasic();}
4.5 自定义登陆失败处理器

如果登陆失败, 也可以通过处理器实现自定义逻辑。
新建com.mirson.spring.boot.security.integrate.handler.SecurityFailureHandler

@Component
@Log4j2
public class SecurityFailureHandler extends SimpleUrlAuthenticationFailureHandler {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,AuthenticationException exception) throws IOException, ServletException {log.info("Process in SecurityFailureHandler ==> login failure.");response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());response.setContentType("application/json;charset=UTF-8");Writer().write(objectMapper.Message()));}
}

将登陆失败的错误信息, 返回给客户端。

修改自定义配置SpringSecurityConfiguration:

@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user/doUserLogin", "/user/userLoginForm","/css/**").permitAll().antMatchers("/user/getUserInfo").authenticated() //hasRole("ADMIN").and().formLogin().loginPage("/user/userLoginForm")    //自定义登录页面.loginProcessingUrl("/user/doUserLogin") // 自定义登陆处理地址.successHandler(securitySuccessHandler)  // 自定义登陆成功处理器.failureHandler(securityFailureHandler)  // 自定义登陆失败处理器.permitAll()            //允许所有人访问该路由.and().csrf().disable()                //暂时禁用csrc否则无法提交.httpBasic();}
4.6 自定义鉴权功能验证
  1. 验证内存模式鉴权

    内存模式我们设置的用户名和密码为admin/admin123

    默认配置文件是admin/admin

    输入admin/admin123, 成功登陆, 内存模式已生效。

  2. 登陆成功处理器验证

    重启服务, 访问获取用户信息接口, 127.0.0.1:22618/user/getUserInfo

    默认是会跳转到登陆页面, 如果没配置登陆成功处理器, 登陆成功后, 会进入上一次访问页面

    可以看到, 登陆成功后, 并没有跳转到上一次访问的用户信息接口, 而是返回了登陆成功处理器的结果。

  3. 登陆失败处理器验证

    同样, 问获取用户信息接口, 127.0.0.1:22618/user/getUserInfo, 会自动跳转到登陆页面。

    采用错误的用户密码, 返回了登陆失败处理器的结果。

5. 总结

Spring Security 提供了鉴权与授权的功能支持, 这里做了详细讲解, 如何使用与配置, 并讲解了自定义鉴权处理功能, 实际业务当中,并非一层不变, 会做不同配置修改,比如自定义资源访问配置, 不同项目有不同的要求, 掌握这些自定义配置, 基本可以覆盖主要的业务场景, 针对更复杂的鉴权, 可以采用oauth2做鉴权处理, 在后续教程中会做讲解。

教程源码下载地址:

本文发布于:2024-01-29 05:20:19,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170647682212981.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Spring   Boot   Security
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23