权限-基于内存的方式实现security(三)
2021/5/4 7:27:27
本文主要是介绍权限-基于内存的方式实现security(三),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
- 新建springboot项目
相关依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--security--> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies>
- security基于内存的方式实现权限认证
application.properties
server.port=8080
config
SecurityConfig
package com.dong.security.config; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { //1. 定义用户详细信息服务 @Override public UserDetailsService userDetailsService(){ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("dong").password(passwordEncoder().encode("123456")).roles("admin").authorities("p1","p2").build()); manager.createUser(User.withUsername("lang").password(passwordEncoder().encode("123456")).roles("student").authorities("p1").build()); //或下面这样写 //manager.createUser(new User("admin",passwordEncoder().encode("123456"), AuthorityUtils.createAuthorityList("p1","p2"))); return manager; } //2. 密码编码器(定义密码是否加密等) //上面的用户信息账户和密码相当于数据库的密码,是正确的密码(接下来需要和我们输入的密码进行比对) // passwordEncoder.encode() 用于加密密码 // passwordEncoder.matchs(原始密码,加密密码)对比原始密码与加密密码 @Bean public PasswordEncoder passwordEncoder() { //加密的方式 return new BCryptPasswordEncoder(); } //3. 安全拦截机制 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/r/**","/login-success").authenticated() //需要认证才能访问 .antMatchers().hasRole("admin")//需要是admin角色 .anyRequest().permitAll()//其它请求都允许 .and() .formLogin() //允许基于Form表单登录验证 .successForwardUrl("/login-success")//自定义登录成功的页面地址(可以不写) .and() .userDetailsService(userDetailsService()); //补充一下用法 //.antMatchers("/r/**").hasRole("ADMIN") //需要相应的角色才能访问(用户拥有角色时) //.anyRequest().authenticated() // 任何请求都需要认证 } }
WebConfig :让首页默认跳转到登录页面
package com.dong.security.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("redirect:/login"); } }
controller
@RestController public class LoginController { //登录成功后的提示信息 @RequestMapping(value = "/login-success" , produces = {"text/plain; charset=UTF-8"}) public String loginSuccess(){ return "登录成功"; } @RequestMapping(value = "/r/r1" , produces = {"text/plain; charset=UTF-8"}) public String r1(){ return "访问资源r1"; } @RequestMapping(value = "/r/r2" , produces = {"text/plain; charset=UTF-8"}) public String r2(){ return "访问资源r2"; } }
- (登录)认证后测试
运行程序访问:http://localhost:8080/ 默认跳转到http://localhost:8080/login显示security自带的登录界面。
输入账户 dong 密码123456 显示:登录成功。
输入账户 lang 密码 123456 显示403:表示没有权限。因为lang不是admi角色而是其它角色。
没登陆前访问:/r/**会跳转到登录界面。
登录成功后访问:http://localhost:8080/r/r1 提示:访问资源r1
访问:http://localhost:8080/logout可以到退出页面(security自带)
- 其它方法实现认证
上面是使用这种方法将用户存入内存
//1. 定义用户详细信息服务 @Override public UserDetailsService userDetailsService(){ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("dong").password(passwordEncoder().encode("123456")).roles("admin").authorities("p1","p2").build()); manager.createUser(User.withUsername("lang").password(passwordEncoder().encode("123456")).roles("student").authorities("p1").build()); //或下面这样写 //manager.createUser(new User("admin",passwordEncoder().encode("123456"), AuthorityUtils.createAuthorityList("p1","p2"))); return manager; }
我们还可以使用下面这种方法替换上面的方法将用户存入内存。
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() //认证信息存储到内存中 .passwordEncoder(passwordEncoder()) .withUser("dong").password(passwordEncoder().encode("123456")).roles("admin") .authorities("p1","p2"); }
改为这种方式后:安全拦截机制不需要.and().userDetailsService(userDetailsService());
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/r/**","/login-success").authenticated() //需要认证才能访问 .antMatchers().hasRole("admin")//需要是admin角色 .anyRequest().permitAll()//其它请求都允许 .and() .formLogin() //允许基于Form表单登录验证 .successForwardUrl("/login-success");//自定义登录成功的页面地址(可以不写) }
- 实现授权
关键语句:antMatchers().hasAnyAuthority()
修改安全拦截机制代码如下
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/r/r1").hasAnyAuthority("p1") .antMatchers("/r/r2").hasAnyAuthority("p2") .antMatchers("/r/**","/login-success").authenticated() //需要认证才能访问 .antMatchers().hasRole("admin")//需要是admin角色 .anyRequest().permitAll()//其它请求都允许 .and() .formLogin() //允许基于Form表单登录验证 .successForwardUrl("/login-success")//自定义登录成功的页面地址(可以不写) .and() .userDetailsService(userDetailsService()); }
- 授权后测试
dong拥有p1和p2权限,登录成功后能访问/r/r1和/r/r2
lang拥有p1权限,登录成功后访问/r1/r1正常返回结果,访问/r/r2报403没有权限的错误。
这篇关于权限-基于内存的方式实现security(三)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27Rocket消息队列资料:新手入门指南
- 2024-11-27rocket消息队资料详解与入门指南
- 2024-11-27RocketMQ底层原理资料详解入门教程
- 2024-11-27RocketMQ项目开发资料:新手入门教程
- 2024-11-27RocketMQ项目开发资料详解
- 2024-11-27RocketMQ消息中间件资料入门教程
- 2024-11-27初学者指南:深入了解RocketMQ源码资料
- 2024-11-27Rocket消息队列学习入门指南
- 2024-11-26Rocket消息中间件教程:新手入门详解
- 2024-11-26RocketMQ项目开发教程:新手入门指南