spring secuirty gradle 简单认证授权

项目结构图

在这里插入图片描述

build.gradle

plugins {
	id 'org.springframework.boot' version '2.1.16.RELEASE'
	id 'io.spring.dependency-management' version '1.0.9.RELEASE'
	id 'java'
	id 'war'
}

group = 'com.sky'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenLocal()
	maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
	maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
	maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
	maven { url 'https://repo.spring.io/snapshot' }
	maven { url 'https://repo.spring.io/milestone' }
	maven { url 'https://plugins.gradle.org/m2/' }
	
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-devtools'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.security:spring-security-test'
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test{
	//useJUnitPlatform()
}

application.yml

server:
  port: 8081

SpringBootGradleApplication

//spring security 启动方法级别的权限控制
@EnableGlobalMethodSecurity(prePostEnabled = true)
@SpringBootApplication
public class SpringBootGradleApplication extends SpringBootServletInitializer{
	public static void main(String[] args) {
		SpringApplication.run(SpringBootGradleApplication.class, args);
	}
	/** 使用外置的tomcat启动,需要继承SpringBootServletInitializer */
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootGradleApplication.class);
	}
}

SysUser 用户信息,用于登录

/**
 * 用户信息,用于登录
 * @author Administrator
 *
 */
public class SysUser {
	private int id;
	private String username;
	private String password;
	
	private List<String> roles;
	
	public SysUser() {}
	public SysUser(int id, String username, String password) {
		this.id = id;
		this.username = username;
		this.password = password;
	}
	//...省略get set
	
	public SysUser addRole(String roleName) {
		if(this.roles == null) {
			this.roles = new ArrayList<>();
		}
		roles.add(roleName);
		return this;
	}
}

用户service类,构造用户数据,并实现UserDetailsService

public interface SysUserService {
	/** 根据账号获取用户 */
	SysUser getUserByAccount(String account);
}
@Service
public class SysUserServiceImpl implements SysUserService , UserDetailsService {
	private static Map<String, SysUser> USER_MAP = new HashMap<>(16);
	static{
		//密码都是123456
		String encodePass = "{bcrypt}$2a$10$t8D4CmkVOCx834key9Mz5OL0M3MJlgd2c4hV3dxfl4zTXgJG1nJu.";
		USER_MAP.put("admin", new SysUser(1,"admin",encodePass).addRole("ROLE_EMPLOYEE").addRole("ROLE_ADMIN"));
		USER_MAP.put("lisa", new SysUser(2,"lisa",encodePass).addRole("ROLE_EMPLOYEE"));
		USER_MAP.put("zhaosi", new SysUser(3,"zhaosi",encodePass));
	}
	@Override
	public SysUser getUserByAccount(String account) {
		return USER_MAP.get(account);
	}
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		if (StringUtils.isEmpty(username)) {
			throw new UsernameNotFoundException("UserDetailsService没有接收到用户账号");
		}
		SysUser sysUser = getUserByAccount(username);
		if (sysUser == null) {
			throw new UsernameNotFoundException(String.format("用户'%s'不存在", username));
		}
		List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
		for (String role : sysUser.getRoles()) {
			// 封装用户信息和角色信息到SecurityContextHolder全局缓存中
			grantedAuthorities.add(new SimpleGrantedAuthority(role));
		}
		return new User(sysUser.getUsername(), sysUser.getPassword(), grantedAuthorities);
	}
	//@Override
	public UserDetails loadUserByUsernameBak(String username) throws UsernameNotFoundException {
		//使用明文密码,默认的加密方式
		//UserDetails user = User.withDefaultPasswordEncoder().username("admin").password("123456").roles("USER_ROLE").build();
		//使用明文密码,需要指定加密方式
		//UserDetails user = User.withUsername("admin").passwordEncoder(passwordEncoder::encode).password("123456").roles("USER_ROLE").build();
		//使用加密密码
		 UserDetails user = User.withUsername("admin").password("{bcrypt}$2a$10$t8D4CmkVOCx834key9Mz5OL0M3MJlgd2c4hV3dxfl4zTXgJG1nJu.").roles("USER_ROLE").build();
		 return user;
	}
}

SecurityConfig:spring security的配置类

@Configuration
@EnableWebSecurity
@Order(1)// 如果配置了多个WebSecurityConfigurerAdapter 
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired PasswordEncoder passwordEncoder;
	@Bean
	PasswordEncoder passwordEncoder() {
		//Spring Security 中提供了 BCryptPasswordEncoder 密码编码工具,可以非常方便的实现密码的加密加盐,相同明文加密出来的结果总是不同
		return PasswordEncoderFactories.createDelegatingPasswordEncoder();
	}
	
	/** 忽略拦截 */
	@Override
	public void configure(WebSecurity web) throws Exception {
		// 直接过滤掉该地址,即该地址不走 Spring Security 过滤器链
		web.ignoring().antMatchers("/ignore","/other");
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//匹配的资源任何人都可以访问
		http.authorizeRequests().antMatchers("/", "/home").permitAll();
		//访问任何资源都需要通过身份验证
		http.authorizeRequests().anyRequest().authenticated();
		//指定登录页面,任何人都可以访问
		http.authorizeRequests().and().formLogin()
			.loginPage("/login")//指定登录页面, spring security有默认的登录页面
			//.successHandler(authenticationSuccessHandler())//登录成功处理,不需要可忽略
			//.failureHandler(authenticationFailureHandler())//登录失败处理,不需要可忽略
			.permitAll().and();
		//指定登出页面,任何人都可以访问
		http.authorizeRequests().and().logout().permitAll().and();
	}
	
	/** 登录成功处理,不需要可忽略 */
	@Bean
	public AuthenticationSuccessHandler authenticationSuccessHandler() {
		return (request,response, authentication) -> {
			System.err.println("登陆成功");
			
			//这里直接写自己的处理逻辑,比如下面这段代码
			response.setContentType("application/json;charset=UTF-8");
			PrintWriter out=response.getWriter();
			out.write("一个JSON串");
		};
	}
	
	/** 登录失败处理,不需要可忽略 */
	@Bean
	public AuthenticationFailureHandler authenticationFailureHandler() {
		return (request,response, e) -> {
			System.err.println("登陆失败");
		};
	}
}

MvcConfig

@Configuration
public class MvcConfig implements WebMvcConfigurer {
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/home").setViewName("home");
		registry.addViewController("/").setViewName("home");
		registry.addViewController("/hello").setViewName("hello");
		registry.addViewController("/login").setViewName("login");
		registry.addViewController("/ignore").setViewName("ignore");
	}
}

controller类用于测试

@RestController
public class UserController {
	 /**
     * 获取登录后的Principal(需要登录)
     */
    @GetMapping("/getPrincipal")
    public Object getPrincipal(@AuthenticationPrincipal Principal principal){
        return principal;
    }

    /**
     * 获取登录后的UserDetails(需要登录)
     */
    @GetMapping("/getUserDetails")
    public Object getUserDetails(@AuthenticationPrincipal UserDetails userDetails) {
        return userDetails;
    }
}
@Controller
@RequestMapping("roletest")
public class RoleTestController {
	/**
     * 跳转到admin.html页面(需要登录,且需要ROLE_ADMIN角色)
     */
    @GetMapping("/admin")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public String admin() {
        return "admin.html";
    }
    /**
     * 跳转到admin.html页面(需要登录,且需要ROLE_ADMIN角色)
     */
    @GetMapping("/employee")
    @PreAuthorize("hasRole('ROLE_EMPLOYEE')")
    public String employee() {
    	return "employee.html";
    }
}

相关html页面

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>

hello.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="Sign Out"/>
        </form>
        <a target="_blank" th:href="@{/getUserDetails}">用户详情</a><br/>
        <a target="_blank" th:href="@{/getPrincipal}">用户最重要信息</a><br/>
        <a target="_blank" th:href="@{/roletest/admin}">管理员能看的页面</a><br/>
        <a target="_blank" th:href="@{/roletest/employee}">员工能看的页面</a><br/>
    </body>
</html>

ignore.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
直接过滤掉该地址,即该地址不走 Spring Security 过滤器链
    </body>
</html>

home.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>home.html</title>
    </head>
    <body>
        <h1>Welcome!</h1>
        <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
    </body>
</html>

admin.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>admin.html</title>
    </head>
    <body>
       	需要登录,且需要ROLE_ADMIN角色
    </body>
</html>

employee.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>employee.html</title>
    </head>
    <body>
       	需要登录,且需要ROLE_EMPLOYEE角色
    </body>
</html>

测试

http://localhost:8081/
该页面不需身份认证,点击here,跳转到 /hello
在这里插入图片描述
因为 /hello需要身份认证,所以转跳到 /login
在这里插入图片描述
使用错误密码登录
在这里插入图片描述
成功登录后
在这里插入图片描述
点击登出,重新回到登录页面
在这里插入图片描述
重新登录后
在这里插入图片描述
点击here,跳转到 /hello,然后分别点击最后4个连接
在这里插入图片描述
在这里插入图片描述
lisa不是管理员所以没有权限查看
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_26264237

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值