0. Add maven dependency
1. Release the homepage login page and static resources
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 用户授权相关()
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 对请求进行授权 先授权再指定其他请求 否则授权无效
.antMatchers("/**/*.css*", "/**/*.js", "/**/*.png", "/**/*.jpg",
"/**/*.jpeg", "/**/*.gif", "/**/*.ico", "/**/fonts/*","/toLogin") // 授权路径
.permitAll() // 无条件访问
;
}
}
2. Specify login information
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 用户授权相关()
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 对请求进行授权 先授权再指定其他请求 否则授权无效
.antMatchers("/**/*.css*", "/**/*.js", "/**/*.png", "/**/*.jpg",
"/**/*.jpeg", "/**/*.gif", "/**/*.ico", "/**/fonts/*","/toLogin") // 授权路径
.permitAll() // 无条件访问
.and()
.authorizeRequests()
.anyRequest() // 其他请求
.authenticated() // 必须经过授权认证
.and()
.formLogin()
.loginPage("/toLogin") // 登录页面
.loginProcessingUrl("/login") // 登录操作地址
.usernameParameter("loginAcct") // 指定登录用户名 name
.passwordParameter("password") // 指定密码 name
.defaultSuccessUrl("/static/admin-main.jsp") // 指定默认登陆成功去的页面
.and().csrf().disable()
;
}
}
3. Memory access
/**
* 用户登录相关
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.userDetailsService(getMyUserDetailsService());
// 内存中指定用户名 密码 进行验证
auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("admin").password("admin").roles("ADMIN")
.and().withUser("gm").password("gm").roles("ADD","EDIT");
}
4. Database user name and password
/**
* 用户登录相关
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 真实环境 数据库方式登陆 用户名验证 登陆封装角色权限信息 都在 userDetailsService
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
// // 内存中指定用户名 密码 进行验证
// auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance())
// .withUser("admin").password("admin").roles("ADMIN")
// .and().withUser("gm").password("gm").roles("ADD","EDIT");
}
5. Implement MyUserDetailsService
package com.gq.mmc.service;
import com.gq.mmc.entity.Admin;
import com.gq.mmc.entity.Role;
import com.gq.mmc.entity.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
IAdminService adminService;
@Autowired
IRoleService roleService;
@Autowired
IAuthService authService;
/**
* 数据库方式检查用户 在此之后完成密码校验
* @param loginAcct
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String loginAcct) throws UsernameNotFoundException {
// 查询出用户信息
Admin user = adminService.getAdminByUsername(loginAcct);
int userId = user.getId();
// 根据userId 查询已分配的角色信息
List<Role> roles = roleService.getAssignedRolesByAdminId(userId);
// 根据userId 查询权限
List<String> auths = authService.getAssignedAuthsByAdminId(userId);
// 封装角色
List<GrantedAuthority> authList = new ArrayList<>();
for (Role role: roles) {
String roleName = "ROLE_" + role.getRoleName();
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(roleName);
authList.add(simpleGrantedAuthority);
}
// 封装权限
for (String authName: auths) {
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authName);
authList.add(simpleGrantedAuthority);
}
// 封装security User对象 由于需要系统用户 其他信息 所以此处使用 扩展了以后的Security User对象
User securtyUser = new SecurityUser(user, authList);
return securtyUser;
}
}
6. Customize the SecurityUser object and integrate the User object to encapsulate the system user object in it
package com.gq.mmc.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
/**
* 由于security User对象只有 username password 信息
* 想要获取系统用户的其他信息 需要以 SecurityUser对 security User对象进行扩展
*/
public class SecurityUser extends User {
// 此处即是 系统 用户名信息
private Admin user;
public SecurityUser(Admin secuser, Collection<? extends GrantedAuthority> authorities) {
// 调用父类构造器 将系统用户的 用户名 密码 传入security User对象 以便下一步进行用户名密码校验
super(secuser.getUserName(), secuser.getUserPswd(), authorities);
// 登陆后将密码置空 防止页面获取密码信息 符合 Spring security 原始置空规则
secuser.setUserPswd(null);
this.user = user;
}
public Admin getUser() {
return user;
}
public void setUser(Admin user) {
this.user = user;
}
}
7. The page displays user information
<!--先添加 Spring security 的权限标签库-->
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
<!--然后在页面 可以根据 标签获取用户信息 注 principal对象里面封装的就是用户对象-->
<security:authentication property="principal.user.userName">
8. Ways to control role access methods
8.1 config control
8.2 annotation control
9. page element control