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去封装传递给前台的。

我目前所了解的如此 若有疏漏还请海涵。欢迎留言讨论

相关文章
相关标签/搜索