在採用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去封裝傳遞給前臺的。
我目前所瞭解的如此 若有疏漏還請海涵。歡迎留言討論