config
CorsConfig.java
package com.x.springsecurityday01.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOriginPatterns("*")
// 是否允许cookie
.allowCredentials(false)
// 设置允许的请求方式
.allowedMethods("GET", "POST", "DELETE", "PUT")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}
SecurityConfig.java
package com.x.springsecurityday01.config;
import com.x.springsecurityday01.dao.UserDao;
import com.x.springsecurityday01.handler.LoginFailHandler;
import com.x.springsecurityday01.handler.LoginSuccessHandler;
import com.x.springsecurityday01.handler.NOAuthHandler;
import com.x.springsecurityday01.handler.NoLoginHandler;
import com.x.springsecurityday01.service.SecurityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled=true)//作用:开启注解式鉴权
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityService securityService;
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
//String encode=passwordEncoder.encode("123");
//自定义用户名和密码
// auth.inMemoryAuthentication().withUser("admin").password(encode).roles("admin");
auth.userDetailsService(securityService);
}
/**
* 自定义登录页面
* @param http
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.formLogin() //告诉框架自定义页面
//.loginPage("/login.html") //登录页面地址
//.loginProcessingUrl("/dologin")//对应表单提交的action
.successHandler(new LoginSuccessHandler())
.failureHandler(new LoginFailHandler())
.permitAll();//对上面两个请求放行
//1.无权限2.未登录而登录
http.exceptionHandling()
.accessDeniedHandler(new NOAuthHandler())
.authenticationEntryPoint(new NoLoginHandler());
/**
* 授权
*/
http.authorizeRequests()
//.antMatchers("/hello").hasAuthority("stu:query")
//.antMatchers("/delete").hasAuthority("stu:query")
//.antMatchers("/hello").hasAnyAuthority("stu:query","hello")
//.antMatchers("/hello").hasRole("stu:query")
//.antMatchers("/delete").permitAll() //配置免拦截方法
.anyRequest().authenticated();//所有请求都拦截
//跨站脚本攻击关闭
http.csrf().disable();
//允许跨域请求
http.cors();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
controller
HelloController.java
package com.x.springsecurityday01.controller;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.security.PermitAll;
@RestController
/**
* @RequestBody+@Controller=@RestController
*/
public class HelloController {
//@Secured("ROLE_stu:query")
//@PermitAll()
@PreAuthorize("hasAuthority('stu:query')")
@RequestMapping("/hello")
public String hello(){
return "hello security";
}
@RequestMapping("/delete")
public String delete(){
return "hello delete";
}
}
dao
UserDao.java
package com.x.springsecurityday01.dao;
import com.x.springsecurityday01.domain.Users;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao {
/**
* 根据账号查用户信息及其权限
*/
Users getUserInfoByAccount(String account);
}
domain
Users.java
package com.x.springsecurityday01.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
private Integer id;
private String username;
private String account;
private String password;
private List<String> anth;//该用户拥有的权限
}
handler
LoginFailHandler.java
package com.x.springsecurityday01.handler;
import com.alibaba.fastjson.JSON;
import com.x.springsecurityday01.util.ResponseResult;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 登陆失败
*/
public class LoginFailHandler implements AuthenticationFailureHandler{
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AuthenticationException e)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
// Map map=new HashMap<>();
// map.put("code",500);
httpServletResponse.getWriter().write(JSON.toJSONString(ResponseResult.LOGIN_FAIL));
}
}
LoginSuccessHandler.java
package com.x.springsecurityday01.handler;
import com.alibaba.fastjson.JSON;
import com.x.springsecurityday01.util.ResponseResult;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 登录成功处理器
*/
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString( ResponseResult.LOGIN_SUCCESS));
}
}
NOAuthHandler.java
package com.x.springsecurityday01.handler;
import com.alibaba.fastjson.JSON;
import com.x.springsecurityday01.util.ResponseResult;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 用户登录成功后,但是访问无权限的接口
*/
public class NOAuthHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AccessDeniedException e)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString( ResponseResult.NO_AUTH));
}
}
NoLoginHandler.java
package com.x.springsecurityday01.handler;
import com.alibaba.fastjson.JSON;
import com.x.springsecurityday01.util.ResponseResult;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 用户未登录,就想访问系统接口
*/
public class NoLoginHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AuthenticationException e)
throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(JSON.toJSONString( ResponseResult.NO_LOGIN));
}
}
service
SecurityService.java
package com.x.springsecurityday01.service;
import com.x.springsecurityday01.dao.UserDao;
import com.x.springsecurityday01.domain.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
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.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SecurityService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDao userDao;
/**
* username:页面传过来的用户名
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Users userInfo=userDao.getUserInfoByAccount(username);
if(userInfo!=null){
String join =String.join(",",userInfo.getAnth());//集合以
//根据username 去数据库查该用户信息
return new User(userInfo.getAccount(),passwordEncoder.encode(userInfo.getPassword()), AuthorityUtils.commaSeparatedStringToAuthorityList(join));
}else {
throw new UsernameNotFoundException("用户不存在");
}
}
}
util
ResponseEnum.java
package com.x.springsecurityday01.util;
public enum ResponseEnum {
LOGIN_SUCCESS(200,"okkk"),
LOGIN_FAIL(500,"faill"),
NO_LOGIN(20001,"NOLOGIN"),
NO_AUTH(5000,"NOAUTH")
;
private Integer code;
private String msg;
ResponseEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
ResponseEnum() {
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
ResponseResult.java
package com.x.springsecurityday01.util;
import lombok.Data;
@Data
public class ResponseResult<T> {
private Integer code;
private String msg;
private T data;
public static final ResponseResult<Void> LOGIN_SUCCESS=
new ResponseResult(ResponseEnum.LOGIN_SUCCESS.getCode(),
ResponseEnum.LOGIN_SUCCESS.getMsg());
public static final ResponseResult<Void> LOGIN_FAIL=
new ResponseResult(ResponseEnum.LOGIN_FAIL.getCode(),
ResponseEnum.LOGIN_FAIL.getMsg());
public static final ResponseResult<Void> NO_LOGIN=
new ResponseResult(ResponseEnum.NO_LOGIN.getCode(),
ResponseEnum.NO_LOGIN.getMsg());
public static final ResponseResult<Void> NO_AUTH=
new ResponseResult(ResponseEnum.NO_AUTH.getCode(),
ResponseEnum.NO_AUTH.getMsg());
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
启动类
Springsecurityday01Application.java
package com.woniu.springsecurityday01;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.x.springsecurityday01.dao")
public class Springsecurityday01Application {
public static void main(String[] args) {
SpringApplication.run(Springsecurityday01Application.class, args);
}
}
UserDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.x.springsecurityday01.dao.UserDao">
<resultMap id="userMap" type="com.x.springsecurityday01.domain.Users">
<result property="id" column="id"></result>
<result property="username" column="username"></result>
<result property="account" column="account"></result>
<result property="password" column="password"></result>
<collection property="anth" ofType="java.lang.String">
<result column="anth_code"></result>
</collection>
</resultMap>
<select id="getUserInfoByAccount" resultMap="userMap">
SELECT
us.id,
us.username,
us.account,
us.password,
ta.anth_code
FROM
users us
left join t_user_anth tua on us.id=tua.user_id
left join t_anth ta on tua.anth_id=ta.id
WHERE account=#{account}
</select>
</mapper>
application.yml
server:
port: 8082
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 111111
mybatis:
mapper-locations: classpath:mapper/*Dao.xml
logging:
level:
com.x.dao: debug
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n'
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.4version>
<relativePath/>
parent>
<groupId>com.woniugroupId>
<artifactId>springsecurityday01artifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springsecurityday01name>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.32version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>2.0.12version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>