spring boot系列--spring security (基于数据库)登录和权限控制

先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 

复制代码
 1 @Configuration
 2 @EnableWebSecurity
 3 public class AuthConfig extends WebSecurityConfigurerAdapter {
 4     @Override
 5     protected void configure(HttpSecurity httpSecurity) throws Exception {
 6         httpSecurity.authorizeRequests()
 7         .antMatchers("/css/**","/staic/**", "/js/**","/images/**").permitAll()
 8         .antMatchers("/", "/login","/session_expired").permitAll()
 9            .and()
10      .formLogin()
11         .loginPage("/login")
12         .defaultSuccessUrl("/main_menu")
13         .failureUrl("/loginError")
14         .usernameParameter("txtUserCd")
15         .passwordParameter("txtUserPwd")
16         .permitAll()
17         .and()
18         .logout()
19         .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
20         .logoutSuccessUrl("/")
21         .deleteCookies("JSESSIONID")
22         .invalidateHttpSession(true)
23         .permitAll()
24         .and()
25         .sessionManagement()
26         .invalidSessionUrl("/session_expired")
27         .maximumSessions(1)
28         .maxSessionsPreventsLogin(true)
29         .expiredUrl("/session_expired");
30         httpSecurity.logout().permitAll();
31 
32     }
33     
34      @Autowired
35      AuthUserService authUserService;
36     public void globalAuthConfig(AuthenticationManagerBuilder auth) throws Exception {
37         auth.userDetailsService(authUserService);
38       //auth.inMemoryAuthentication().withUser("user").password("password");
39     }
40     /*@Configuration
41     protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
42         @Autowired
43         AuthUserService authUserService;
44     
45         @Override
46         public void init(AuthenticationManagerBuilder auth) throws Exception {
47             //auth.inMemoryAuthentication().withUser("user").password("password");
48             auth.userDetailsService(authUserService);
49         }
50     }*/
51 }
复制代码

一、configur方法 基本配置

No Source Comment
L1 @Configuration 这个就是java形式的bean spring3.0以后 允许以 @Configuration 注解来代替XML形式的bean
L2 @EnableWebSecurity 用这个注解开启 spring security配置验证开启
L3 WebSecurityConfigurerAdapter 这个需要我们继承WebSecurityConfigurerAdapter适配器且重写

 configure 函数 来实现访问的控制(那些访问/资源 需要哪些权限)和登录的验证(数据库验证/内存验证)

L6 authorizeRequests() 通过authorizeRequests()配下的子函来完成访问/授权 配置
L7,8 antMatchers/permitAll antMatchers里配置的资源是可以被所有用户访问(permitAll)的
L9 and() 类似于结束标签
L10 formLogin 通过formLogin()配下的函数对登录form进行配置
L11 loginPage 设置登录页面
L12 defaultSuccessUrl 默认登录成功跳转地址
L13 failureUrl 默认登录失败跳转地址
L14,15 usernameParameter
passwordParameter
用户名密码验证用 *这里的参数要和画面上控件名保持一致
L18  logout() 通过logout()配下的函数对注销进行配置
L19 .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 设置注销用的请求URL
L20 logoutSuccessUrl 设置注销成功后的跳转URL
L21 deleteCookies 消除Cookie
L22 invalidateHttpSession 销毁Session
L25 sessionManagement 通过sessionManagement配下的函数对session配置
L27 maximumSessions 同一用户session上限设定 *比如同一个用户 多次登录
L28 maxSessionsPreventsLogin maximumSessions设定的上限启用 * 超出报错
L29 expiredUrl

超过session上限跳转URL设定

 

 二、globalAuthConfig方法 认证

先说L38 这行注掉的 是内存认证模式  意思是创建了一个 名为user 密码 为password的用户

然后是 L37 这也是认证核心

先看一下这个 传入参数的的构成 也就是 AuthUserService 类

复制代码
 1 @Service
 2 public class AuthUserService implements UserDetailsService{
 3 
 4     @Autowired
 5     MstUsersMapper mstUsersMapper;
 6     
 7     @Override
 8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 9         Users users =mstUsersMapper.selectByPrimaryKey(username);
10         if(users == null) {
11             throw new UsernameNotFoundException("User not found for name:"+username);
12         }
13         return new AuthUser(users);
14     }
15     
16     public String getAuthorityByLoginId(String loginId ){
17         //Map<String,String> authKindMap = new HashMap<String,String>();
18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
19         return auth;
20     }
21 }
复制代码

可以看到我们是 实现了UserDetailsService 然后重写了一个loadUserByUsername和追加了一个 getAuthorityByLoginId函数

关于 getAuthorityByLoginId 好说的基本上就是 当前用户的权限

然后是loadUserByUsername

可以通过名字基本上可以看的出是 通过name 取user 的信息 实际上也是这样 这里并不判断你输的密码对不对 主要是

判断你输入的用户名在数据库里存不存在 不存在 报错 扔出 存在 实例化一个 AuthUser 返回

这个AuthUser 类也很重要 实现了UserDetails  如下

复制代码
 1 public class AuthUser implements UserDetails {
 2     private static final long serialVersionUID = 1L;
 3     
 4     private String userId;
 5     private String loginId;
 6     private String password;
 7     private String authorityKind;
 8     public AuthUser(Users users) {
 9         super();
10         this.userId = users.getUserId();
11         this.loginId = users.getLoginId();
12         this.password = users.getPassword();
13         this.authorityKind = users.getAuthorityKind();
14     }
15 
16     @Override
17     public Collection<GrantedAuthority> getAuthorities() {
18         List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
19         list.add(new SimpleGrantedAuthority(authorityKind));
20         return list;
21     }
22 
23     @Override
24     public String getPassword() {
25         return password;
26     }
27 
28     @Override
29     public String getUsername() {
30         return loginId;
31     }
32 
33     @Override
34     public boolean isAccountNonExpired() {
35         return true;
36     }
37 
38     @Override
39     public boolean isAccountNonLocked() {
40         return true;
41     }
42 
43     @Override
44     public boolean isCredentialsNonExpired() {
45         return true;
46     }
47 
48     @Override
49     public boolean isEnabled() {
50         return true;
51     }
复制代码

 这里的几个点要注意一下

L17 getAuthorities 它返回了一个权限集合 这个集合是和你在画面侧用的hasAnyAuthority('ROLE_USER','ROLE_ADMIN') 这个函数相呼应的

换言之你之所以能在画面侧如上那样写也是因为你在这里吧把当前用户的权限set进去了

 

然后看一下我们实现的 UserDetails这个父类,如下官网文档给的信息.

NoModifier and TypeMethod and Description
1 java.util.Collection<? extends GrantedAuthority> getAuthorities()
Returns the authorities granted to the user.
2 java.lang.String getPassword()
Returns the password used to authenticate the user.
3 java.lang.String getUsername()
Returns the username used to authenticate the user.
4 boolean isAccountNonExpired()
Indicates whether the user's account has expired.
5 boolean isAccountNonLocked()
Indicates whether the user is locked or unlocked.
6 boolean isCredentialsNonExpired()
Indicates whether the user's credentials (password) has expired.
7 boolean isEnabled()
Indicates whether the user is enabled or disabled.

 

 前3个应该不用说了,从第四个开始说一下

isAccountNonExpired():当前账号是否已经过期

isAccountNonLocked():当前账号是否被锁

isCredentialsNonExpired():当前账号证书(密码)是否过期

isEnabled():当前账号是否被禁用

都要给设成true 否则登录会报出来

还有实现一个UserDetailsService类如下

复制代码
 1 @Service
 2 public class AuthUserService implements UserDetailsService{
 3 
 4     @Autowired
 5     MstUsersMapper mstUsersMapper;
 6     
 7     @Override
 8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 9         Users users =mstUsersMapper.selectByPrimaryKey(username);
10         if(users == null) {
11             throw new UsernameNotFoundException("User not found for name:"+username);
12         }
13         return new AuthUser(users);
14     }
15     
16     public String getAuthorityByLoginId(String loginId ){
17         //Map<String,String> authKindMap = new HashMap<String,String>();
18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
19         return auth;
20     }
21 }
复制代码
如你看到那样loadUserByUsername这函数并不做密码验证只是拿username取用户信息,当然取不到报错
取到交给AuthUser,然后spring boot 自己再去判断密码,以及前面说的那个几个check
剩下的就是 Controller这个就没有特别要说的到git上看代码就完了
最后贴一下执行效果图及git地址

(完)

posted @ 2018-01-15 19:33  挨踢人啊  阅读(10089)  评论(0编辑  收藏  举报