🍁登录认证
加入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置文件config类:
package com.nice.blog.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 10:40
*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
public static void main(String[] args) {
//加密策略 MD5 不安全 彩虹表 MD5 加盐
String nice = new BCryptPasswordEncoder().encode("nice");
System.out.println(nice);
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() //开启登录认证
// .antMatchers("/user/findAll").hasRole("admin") //访问接口需要admin的角色
.antMatchers("/css/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/plugins/**").permitAll()
.antMatchers("/admin/**").access("@authService.auth(request,authentication)") //自定义service 来去实现实时的权限认证
.antMatchers("/pages/**").authenticated()
.and().formLogin()
.loginPage("/login.html") //自定义的登录页面
.loginProcessingUrl("/login") //登录处理接口
.usernameParameter("username") //定义登录时的用户名的key 默认为username
.passwordParameter("password") //定义登录时的密码key,默认是password
.defaultSuccessUrl("/pages/main.html")
.failureUrl("/login.html")
.permitAll() //通过 不拦截,更加前面配的路径决定,这是指和登录表单相关的接口 都通过
.and().logout() //退出登录配置
.logoutUrl("/logout") //退出登录接口
.logoutSuccessUrl("/login.html")
.permitAll() //退出登录的接口放行
.and()
.httpBasic()
.and()
.csrf().disable() //csrf关闭 如果自定义登录 需要关闭
.headers().frameOptions().sameOrigin();// 支持iframe页面嵌套
}
}
创建admin实体类:
package com.nice.blog.admin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 10:58
*/
@Data
public class Admin {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
}
创建AdminService:
package com.nice.blog.admin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nice.blog.admin.entity.Admin;
import com.nice.blog.admin.mapper.AdminMapper;
import com.nice.blog.admin.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 11:03
*/
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public Admin findAdminByUsername(String username) {
LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Admin::getUsername,username);
queryWrapper.last("limit 1");
Admin admin = adminMapper.selectOne(queryWrapper);
return admin;
}
}
建立AuthService类:(主要写权限认证方法)
package com.nice.blog.admin.service;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 11:19
*/
@Service
public class AuthService {
public boolean auth(HttpServletRequest request, Authentication authentication){
return true;
}
}
建立SecurityUserService类:
添加到spring容器中:
package com.nice.blog.admin.service;
import com.nice.blog.admin.entity.Admin;
import org.springframework.beans.factory.annotation.Autowired;
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.Component;
import java.util.ArrayList;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 10:52
*/
@Component
public class SecurityUserService implements UserDetailsService {
@Autowired
private AdminService adminService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//登录的时候会把 username 传递到这里
//通过username查询 admin表 如果admin存在 将密码告诉spring security
//如果不存在 返回null 认证失败
Admin admin = adminService.findAdminByUsername(username);
if(admin == null){
return null;
}
UserDetails userDetails = new User(username,admin.getPassword(),new ArrayList<>());
//new ArrayList<>()为认证授权类,为null
return userDetails;
}
}
🍁权限认证
自定义service 来去实现实时的权限认证
在AuthService 里实现:
package com.nice.blog.admin.service;
import com.nice.blog.admin.entity.Admin;
import com.nice.blog.admin.entity.Permission;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @Description: 权限认证
* @Author : Jerry
* @create : 2022-08-27 11:19
*/
@Service
public class AuthService {
@Autowired
private AdminService adminService;
public boolean auth(HttpServletRequest request, Authentication authentication){
//权限认证
//请求路径
String requestURI = request.getRequestURI();
Object principal = authentication.getPrincipal(); //用户信息
if(principal == null || "anonymousUser".equals(principal)){//匿名用户
return false;
}
UserDetails userDetails = (UserDetails) principal;
String username = userDetails.getUsername();
Admin admin = adminService.findAdminByUsername(username);
if(admin == null){
return false;
}
if(1 == admin.getId()){
//超级管理员
return true;
}
Long id = admin.getId();
List<Permission> permissionList = this.adminService.findAdminByAdminId(id);
requestURI = StringUtils.split(requestURI,'?')[0]; //取到前面不到参数的那一部分
for(Permission permission:permissionList){
if(requestURI.equals(permission.getPath())){
return true;
}
}
return false;
}
}
实现findAdminByAdminId方法:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 11:03
*/
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
//.....
@Override
public List<Permission> findAdminByAdminId(Long id) {
return adminMapper.findPermissionByAdminId(id);
}
}
//不想建xml的话,也可以在mapper接口中直接写。
package com.nice.blog.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nice.blog.admin.entity.Admin;
import com.nice.blog.admin.entity.Permission;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-27 10:58
*/
@Repository
public interface AdminMapper extends BaseMapper<Admin> {
//不想建xml的话,也可以直接写。
@Select("select * from ms_permission where id in(select permission_id from ms_admin_permission where admin_id = #{id})")
List<Permission> findPermissionByAdminId(Long id);
}