权限部分是一个后台系统必备的部分,之前spring的操作,我基本是利用shiro配置整合,也有尝试其他的权限框架,自己也写过自己的权限部分,主要是利用拦截器和http的组合操作达成权限控制的效果。那么话不多说,现在是讲讲springBoot的部分,最近用到了springboot整合权限框架部分的内容.

             这边单纯利用jsp,不使用模板类型,主要是便于理解,网上的模板类通常都是一半代码,一半靠猜,精彩部分就脱身而去。怪坑的、屁话不说,代码解析一波



简单例子与介绍


spring security3 这本书简介了整个过程



主要来说,整个过程都是基于过滤器拦截并将请求封装 成为一个验证信息,给验证管理者验证,通过后为此请求认证并通过访问。否则抛出认证异常。




AbstractAuthenticationProcessingFilter这个过滤器是符合springSecurity的一个过滤器,内部包含了一堆对请求的处理方法




springboot 加入混淆_System



AuthenticationManager 这个接口显然是验证管理者,旗下仅有个ProviderManager方法


springboot 加入混淆_spring_02


这里有个权限验证列表,显然这是用来管理谁来管理权限的,这个才是真正的认证决策的方法



springboot 加入混淆_spring_03



内部包含获取权限,详情,是否验证等一系列方法
Object getPrincipal()                                                   返回安全实体的唯一标识(如,一个用户名)
Object getCredentials()                                               返回安全实体的凭证信息 
List<GrantedAuthority> getAuthorities()                        得到安全实体的权限集合,根据认证信息的存储决定的。
Object getDetails()                                                      返回一个跟认证提供者相关的安全实体细节信息 
boolean isAuthenticated ()                                            是否认证成功
void setAuthenticated(boolean paramBoolean)  throws IllegalArgumentException;      设置认证状态
然后最基本的一个方法就实现了


/**
	* @ClassName: AuthenticationExample
	* @Description: 简单例子
	* @author linge
	* @date 2017年12月4日 上午10:28:18
	*
	*/
	public class AuthenticationExample {  
		//设置简单的认证管理,继承了AuthenticationManager
		  private static AuthenticationManager am = new SampleAuthenticationManager();  
		  public static void main(String[] args) throws Exception {  
			  //相当于无限获取验证信息
		    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));  
		    while(true) {  
		      System.out.println("Please enter your username:");  
		      String name = in.readLine();  
		      System.out.println("Please enter your password:");  
		      String password = in.readLine();  
		      try {  
		    	  //模拟请求,执行登录的过滤器
		        Authentication request = new UsernamePasswordAuthenticationToken(name, password);  
		        Authentication result = am.authenticate(request);  
		        //用于保存到全局中就像我们做登陆时候用的session一样,用来存储当前登陆的用户信息,
				/* 个请求一个的话,如何保证下一个请求,还能保留住上次的session,其实这个过滤器在清除SecurityContextHolder之前,
				        先把SecurityContext拷贝出来放到session中,使用session的名称是HttpSessionSecurityContextRepository.
				   SPRING_SECURITY_CONTEXT_KEY(“SPRING_SECURITY_CONTEXT”)。
				   下次请求来的时候,会先读session中这个值,如果没有的话才会创建新的,否则就使用session中的。
				*/   
		        SecurityContextHolder.getContext().setAuthentication(result);  
		        break;  
		      } catch(AuthenticationException e) {  
		        System.out.println("Authentication failed: " + e.getMessage());  
		      }  
		    }  
		    System.out.println("Successfully authenticated. Security context contains: " +  
		              SecurityContextHolder.getContext().getAuthentication());  
		  }  
		}  
		//验证管理器
		class SampleAuthenticationManager implements AuthenticationManager {  
			//设置认证状态,赋予权限
		  static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();  
		  static {  
		    AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));  
		  }  
		  public Authentication authenticate(Authentication auth) throws AuthenticationException {  
		    if (auth.getName().equals(auth.getCredentials())) {  //验证信息
		    	//赋予权限与认证
		      return new UsernamePasswordAuthenticationToken(auth.getName(),  
		        auth.getCredentials(), AUTHORITIES);  //这里直接获取权限
		      }  
		      throw new BadCredentialsException("Bad Credentials");  
		  }  
		}





实例介绍


使用官方 WebSecurityConfigurerAdapter  修改


1、数据库结构


2、sql

   

CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `detail` varchar(30) DEFAULT NULL COMMENT '详情',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
CREATE TABLE `sys_role_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `Sys_User_id` int(11) DEFAULT NULL,
  `Sys_Role_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `Sys_User_id` (`Sys_User_id`,`Sys_Role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8



CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(20) DEFAULT NULL COMMENT '用户名',
  `password` varchar(20) DEFAULT NULL COMMENT '密码',
  `mark` varchar(20) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8




表数据根据自己喜好填写

3、pom.xml
<!--springSecurity-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>


4、取代默认访问页面

/**
* @ClassName: WebMvcConfig
* @Description: 用于配置默认登录界面
* @author linge
* @date 2017年10月10日 上午9:15:21
*
*/
@Configuration

public class WebMvcConfig extends WebMvcConfigurerAdapter{
//	springMVC 配置,注册访问 /login 转向 login.html 页面
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}

5、取代默认登入,如果是默认情况,在启动项目的时后会在下方显示出密码。

/**
* @ClassName: WebSecurityConfig
* @Description: 校验
* @author linge
* @date 2017年10月10日 上午9:15:10
*
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled= true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	
    @Bean
    UserDetailsService customUserService(){ //注册UserDetailsService 的bean
        return new CustomUserService();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserService()); //user Details Service验证

    }
    /*忽略的请求*/
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/photo/**","/js/**","/include/**","/images/**","/assets/**","/upload/**");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	 http.csrf().disable().authorizeRequests()//这个不加进不去,登录验证的时候是post请求
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and()
                .formLogin()
                .loginPage("/login")
                .successForwardUrl("/")
                .failureUrl("/login?error")
                .permitAll() //登录页面用户任意访问
                .and()
                .headers().frameOptions().disable()//开启允许iframe
                .and()
                .logout().permitAll(); //注销行为任意访问
    }
}




注册认证服务的类

/**
* @ClassName: CustomUserService
* @Description: TODO(这里用一句话描述这个类的作用)
* @author linge
* @date 2017年9月30日 下午12:17:52
*
*/
@Service
@Transactional
public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口

    @Autowired
    UserDao userDao;	

    @Override
    public UserDetails loadUserByUsername(String username) { //重写loadUserByUsername 方法获得 userdetails 类型用户

        SysUser user = userDao.findByUserName(username);
        if(user == null){
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //用于添加用户的权限。只要把用户权限添加到authorities 就万事大吉。
        for(SysRole role:user.getRoles())
        {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
            System.out.println(role.getName());
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(),
                true,//是否可用
                true,//是否过期
                true,//证书不过期为true
                true,//账户未锁定为true;这4个参数可省略
                authorities);
    }




页面放置

springboot 加入混淆_spring_04


application.properties

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp


如果有不理解和不正确的地方,请麻烦指出一下,大家共同进步,剩下的,结合之前的springBoot基础搭建的内容就能跑通了