本文主要是介绍Spring Security注解方式权限控制过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教...
一、摘要
Spring Security除了可以在配置文件中配置权限校验规则,还可以使用注解方式控制类 中方法的调用。
例如Controller中的某个方法要求必须具有某个权限才可以访问,此时就 可以使用Spring Security框架提供的注解方式进行控制。
二、实现步骤
2.1 在配置类中添加权限注解的支持
package com.by.config; //import com.by.service.UserService; import com.by.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * spring security 核心配置 */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解支持 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired private PasswordEncoder passwordEncoder; /** * 配置认证信息的来源 * AuthenticationManagerBuilder认证管理器 */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置认证提供者 auth.userDetailsService(userService).passwordEncoder(passwordEncoder);//配置认证提供者 super.configure(auth);//密码 } /** * 配置web的安全(忽略的静态资源) * * @param web * @throws Exception */ @Override public void configure(WebSecurity web) throws Exception { //web.ignoring().antMatchers("/pages/a.html","/pages/b.html"); //web.ignoring().antMatchers("/pages/**"); //指定login.html页面可以匿名访问 web.ignoring().antMatchers("/login.html"); } /** * 配置HTTP请求的安全(认证、授权、退出) * HttpSecurity 用于构建一个安全过滤器链 SecurityFilterChain * * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { // super.configure(http); http.formLogin() .loginPage("/login.html")// 默认页面 .loginProcessingUrl("/login")//请求 .usernameParameter("username") .passwordParameter("password") // 请求成功后访问哪个路径 .defaultSuccessUrl("/index.html",true); //权限配置 http.authorizeRequests() //.antMatchers("pages/a.html").authenticated() .antMatchers("/pages/b.html").hasAuthority("add") /** * 拥有ROLE_ADMIN可以访问d页面 * 注意:此处虽然写的是ADMIN,但是框架会自动添加前缀ROLE_ */ .antMatchers("pages/c.html").hasRole("ADMIN") // 其他资源均需要登录后访问 .anyRequest().authenticated(); // super.configure(http); //关闭跨站请求防护 http.csrf().disable(); } /** * 配置加密对象 * @return */ @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
2.2 创建Controller类
在Controller的方法上加入注解进行权限控制
package com.by.controller; import org.springframework.security.Access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/hello") public class HelloController { @RequestMapping("/add") /** * 表示用户要拥有add权限 才能访问该方法 */ @PreAuthorize("hasAuthority('add')") public String add(){ System.out.println("add"); return "success"; } }
2.3 UserService类
package com.by.service; www.chinasem.cn import com.by.pojo.UserInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import Java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Component public class UserService implements UserDetailsService { @Autowired private PasswordEncoder passwordEncoder; //模拟向数据库中插入数据 public Map<String, UserInfo> map = new HashMap<>(); public void init() { UserInfo u1 = new UserInfo(); u1.setUsername("admin"); u1.setPassword(passwordEncoder.encode("123")); UserInfo u2 = new UserInfo(); u2.setUsername("user"); u2.setPassword(passwordEncoder.encode("123")); map.put(u1.getUsername(), u1); map.put(u2.getUsername(), u2); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { init(); System.out.println("username:" + username); //模拟从数据库中查询用户 javascript UserInfo userInfo = map.get(username); if (userInfo == null) { return null; } //模拟查询数据库中用户的密码 去掉明文标识{noop} String password = userInfo.getPassword(); List<GrantedAuthority> list = new ArrayList<>(); //授权,后期需要改为查询数据库动态获得用户拥有的权限和角色 if (username.equals("admin")) { list.add(new SimpleGrantedAuthority("add")); list.add(new SimpleGrantedAuthority("delete")); } list.add(new SimpleGrantedAuthority("ROLE_ADMIN")); User user = new User(username, password, list); return user; } public static void main(String[] args) { for (int i = 0; i < 3; i++) { String password="123456"; /** * BCryptPasswordEncoder是Spring Security * 提供的一个加密的API */ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String hashPassWord = bCryptPasswordEncoder.encode(password); System.out.println(hashPassWord); boolean flag = bCryptPasswordEncoder.matches("123456", hashPassWord); System.out.println(flag); } } }
三、测试
可以看出admin有add方法的访问权限,而user则没有add方法的访问权限
3.1 user测试
3.2 admin 测试
四、退出登录功能
用户完成登录后Spring Security框架会记录当前用户认证状态为已认证状态,即表示用 户登录成功了。
那用户如何退出登录呢?我们可以配置类中进行如下 配置:
package com.by.config; //import com.by.service.UserService; import com.by.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * spring security 核心配置 */ @Configuration @EnjsableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解支持 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired private PasswordEncoder passwordEncoder; /** * 配置认证信息的来源 * AuthenticationManagerBuilder认证管理器 */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置认证提供者 auth.userDetailsService(userService).passwordEncoder(passwordEncoder);js//配置认证提供者 super.configure(auth);//密码 } /** * 配置web的安全(忽略的静态资源) * * @param web * @throws Exception */ @Override public void configure(WebSecurity web) throws Exception { //web.ignoring().antMatchers("/pages/a.html","/pages/b.html"); //web.ignoring().antMatchers("/pages/**"); //指定login.html页面可以匿名访问 web.ignoring().antMatchers("/login.html"); } /** * 配置HTTP请求的安全(认证、授权、退出) * HttpSecurity 用于构建一个安全过滤器链 SecurityFilterChain * * @param http * @throws Exception */ @Override 编程protected void configure(HttpSecurity http) throws Exception { // super.configure(http); http.formLogin() .loginPage("/login.html")// 默认页面 .loginProcessingUrl("/login")//请求 .usernameParameter("username") .passwordParameter("password") // 请求成功后访问哪个路径 .defaultSuccessUrl("/index.html",true); //权限配置 http.authorizeRequests() //.antMatchers("pages/a.html").authenticated() .antMatchers("/pages/b.html").hasAuthority("add") /** * 拥有ROLE_ADMIN可以访问d页面 * 注意:此处虽然写的是ADMIN,但是框架会自动添加前缀ROLE_ */ .antMatchers("pages/c.html").hasRole("ADMIN") // 其他资源均需要登录后访问 .anyRequest().authenticated(); /** * 退出登录 */ http.logout() .logoutUrl("/logout") .logoutSuccessUrl("/login.html").invalidateHttpSession(true); // super.configure(http); //关闭跨站请求防护 http.csrf().disable(); } /** * 配置加密对象 * @return */ @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
在a.html 设置一个退出登录的超链接
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 我是b.html <a href="/logout" rel="external nofollow" >退出登录</a> </body> </html>
测试
登录后访问localhost:8083/pages/a.html 然后点击退出登录。
如果用户要退出登录,只需要请求/logout这个URL地址就 可以,最后页面会跳转到login.html页面
总结
这篇关于Spring Security注解方式权限控制过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!