在采用Spring Security去控制用户访问资源的时候,因为Spring Boot 全局应该采用的是注解形式去配置各个模块。因此咱们在这里除了写XML文件外。还有一种方法。就是采用注解去管理这二者。html
在 Spring boot 的pom中添加 Spring security 的依赖:java
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
这个是Spring boot 和security的集成包。web
咱们在Spring Security 中了解到。Security会有权限管理器。来规定用户的行为。spring
如今咱们须要作的也是去建立这个管理器。sql
而后咱们建立一个类 继承WebSecurityConfigurerAdapter 他有两个configure方法 去实现 只不过参数不一样。其中一个参数是HttpSecurity http 还有一个是AuthenticationManagerBuilder authapache
咱们对比以前的配置文件 sec:http 标签 是用来规定用户那些资源能够请求,那些资源须要被拦截。json
而sec:authentication-manager 是用来告诉Security 认证规则。session
因此 咱们可以推测出这两个方法的做用(查看相关文档也是如此)mybatis
在configure(HttpSecurity http)方法里 咱们来肯定。那些资源须要被拦截app
在configure(AuthenticationManagerBuilder auth)方法里 咱们来肯定。认证规则。
代码以下:
package RestFul; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationProvider; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetailsService; import Dao.AuthuserService; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled=true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ private SqlSessionFactory sqlSessionFactory; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() //全部请求都须要被认证。 .and() //登录方法。注意:因为我有采用thymeleaf 因此这里我直接定位的是方法。这个方法不作任何操做 返回值就是"login" //而后定位到src/main/resources/templates目录下的 login.html 文件。 //若是不用thymeleaf 这里须要写下你的登录页面界面 //登录成功 跳转的方法为 main (方法内容 同login 直接跳转到main.html) //登陆失败 跳转到 error.html .formLogin().loginPage("/login").successForwardUrl("/main").failureForwardUrl("/error.html").permitAll() .and() //自定义登录页面的时候spring security 默认须要csrf 这么一个参数。在这里咱们能够关闭 .httpBasic().and().csrf().disable(); // http.authorizeRequests().antMatchers("/").permitAll(); // http.authorizeRequests().antMatchers("*.js").permitAll(); // http // .authorizeRequests() // .antMatchers("/").hasRole("ADMIN") // .anyRequest().authenticated() // .and() // .formLogin() // .loginPage("/login") // .permitAll() // .and() // .logout() // .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //建立一个认证规则AuthuserService auth.userDetailsService(new AuthuserService(sqlSessionFactory)); // auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); } public SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } @Autowired public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { System.out.println("session factory is : ["+sqlSessionFactory+"]"); this.sqlSessionFactory = sqlSessionFactory; } }
在此。咱们要注意@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true) 三个标签。EnableWebSecurity标签 The WebSecurityConfig
class is annotated with @EnableWebSecurity
to enable Spring Security’s web security support and provide the Spring MVC integration.
来自官方文档
而EnableGlobalMethodSecurity 标签来实现受权,实现用户对某个操做是否有权限的控制.
在上面的类中 咱们使用auth.userDetailsService(new AuthuserService(sqlSessionFactory)); 建立了一个认证 这个认证类以下:
package Dao; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.support.SqlSessionDaoSupport; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 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 pojo.role; import pojo.user; @Configuration public class AuthuserService extends SqlSessionTemplate implements UserDetailsService{ public AuthuserService(SqlSessionFactory sqlSessionFactory) { super(sqlSessionFactory); } public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserServices us=new UserServices(getSqlSessionFactory()); List<role> list=us.getRoleByusername(username); user u=us.getUserByusername(username); System.out.println(list); //权限列表 因为Spring security 4 去掉了GrantedAuthorityImpl 这个是Spring security3 里的 GrantedAuthority 的实现类 //这里替换的 是SimpleGrantedAuthority 类 进行权限的封装 List<GrantedAuthority> rolelist=new ArrayList<GrantedAuthority>(); for (int i = 0; i < list.size(); i++) { role rol=list.get(i); System.out.println(rol.getRoleCode()); GrantedAuthority gi=new SimpleGrantedAuthority(rol.getRoleCode()); rolelist.add(gi); } return new User(username, u.getPassword(), rolelist); } }
SimpleGrantedAuthority是GrantedAuthority的实现类
而咱们来控制那个方法须要什么权限 须要在Spring boot 的Controller中 在方法上使用@PreAuthorize("hasRole('ROLE_SERVICE')")标签 规定 某某方法须要什么样的权限。这样 整个Spring Security 就能够对Springboot 中的资源进行管理了。
贴上个人控制类:
package RestFul; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.SessionAttribute; import org.springframework.web.bind.annotation.SessionAttributes; import pojo.user; import Dao.UserServices; @Controller//根据返回的字符串去定位 页面 注意 字符串应该和页面同名 @RestController//返回json字符串 @SessionAttributes("userid") public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); private SqlSessionFactory sqlsessionFactory; @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } @RequestMapping("/test") @ResponseStatus(value=HttpStatus.BAD_GATEWAY) public String test(@RequestParam(value="username",defaultValue="zhangxing") String username,@RequestParam(value="password",defaultValue="zhangxing") String password) { user u=new user(1,username, password,1); return "this is defind String"; } @RequestMapping(path="/index") public List<Greeting> index(@RequestParam(value="name", defaultValue="World") String name) { Greeting g1= new Greeting(1,String.format(template, name)); Greeting g2= new Greeting(2,String.format(template, name)); List<Greeting> list=new ArrayList<Greeting>(); list.add(g1); list.add(g2); return list; } @RequestMapping("/map") public Map<String,Greeting> map(@RequestParam(value="name", defaultValue="World") String name) { Greeting g1= new Greeting(1,String.format(template, name)); Greeting g2= new Greeting(2,String.format(template, name)); Map<String,Greeting> map=new HashMap<String, Greeting>(); map.put("index1", g1); map.put("index2", g2); return map; } @RequestMapping("/main") @PreAuthorize("hasRole('ROLE_SERVICE')") public String main(Model model) { model.addAttribute("name", "zx"); model.addAttribute("user", getPrincipal()); return "main"; } @RequestMapping("/users") public String users(Model model) { UserServices us=new UserServices(sqlsessionFactory); model.addAttribute("users", us.getUsers()); model.addAttribute("userid", counter.incrementAndGet()); model.addAttribute("user", getPrincipal()); return "user"; } @RequestMapping("/login") public String login(Model model){ model.addAttribute("user", getPrincipal()); return "login"; } @RequestMapping("/argular") public String argular(){ return "argular"; } private String getPrincipal(){ String userName = null; Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { userName = ((UserDetails)principal).getUsername(); } else { userName = principal.toString(); } return userName; } public SqlSessionFactory getSqlsessionFactory() { return sqlsessionFactory; } public void setSqlsessionFactory(SqlSessionFactory sqlsessionFactory) { this.sqlsessionFactory = sqlsessionFactory; } }
ps: 使用Spring boot 是抛出xml/json格式数据 仍是根据返回字符串去寻找页面 依赖于@Controller
@RestController 这两个标签
附上thymeleaf 的pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
而后再html页面中 用<html xmlns:th="http://www.thymeleaf.org"> 标签引入thymeleaf 这样就可使用th:***去解释相关值。废话一句 这个值 是经过Controller 的 model去封装传递给前台的。
我目前所了解的如此 若有疏漏还请海涵。欢迎留言讨论