Spring Boot+Spring Security的相關事項

        在採用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去封裝傳遞給前臺的。

我目前所瞭解的如此 若有疏漏還請海涵。歡迎留言討論

相關文章
相關標籤/搜索