SpringSecurity

SpringSecurity

一、引入依赖

<dependency> 
	<groupId>org.springframework.boot</groupId> 	
	<artifactId>spring-boot-starter-security</artifactId> 
	<version>2.2.0.RELEASE</version>
</dependency>

二、后端代码

(1)、配置类编写

1、配置PasswordEncoder密码编码器

@Configuration 
public class SecurityConfig { 
	@Bean 
	public PasswordEncoder getPwdEncoder(){ 
		return new BCryptPasswordEncoder();
	}
}

2、修改配置类

  • successForwardUrl()登录成功后跳转地址
  • loginPage() 登录页面
  • loginProcessingUrl登录页面表单提交地址,此地址可以不真实存 在。
  • antMatchers():匹配内容
  • permitAll():允许
@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
	@Override 
	protected void configure(HttpSecurity http) throws Exception { 
		// 表单认证 
		http.formLogin() 
		.loginProcessingUrl("/login") //当发现/login 时认为是登录,需要执行UserDetailsServiceImpl 
		.successForwardUrl("/toMain") //此处是 post 请求 
		.failureForwardUrl("/fail")//登录失败跳转地址
		.loginPage("/toLogin")
		.usernameParameter("myusername") //自定义前端参数名称
		.passwordParameter("mypassword");
		// url 拦截 http.authorizeRequests() .antMatchers("/login.html") .permitAll() 		
		//login.html 不需要被认证 .anyRequest().authenticated();
		//所有的请求都必须被认证。必须登录后才能访问。
		//关闭 csrf 防护 
		http.csrf().disable();
		// url 拦截 
		http.authorizeRequests() 
		.antMatchers("/login.html")
		.permitAll() //login.html 不需要被认证
		.antMatchers("/fail.html")
		.permitAll() //fail.html 不需要被认 证 
		.anyRequest().authenticated();//所有的请求都必须被认证。必 须登录后才能访问。
	 }
	@Bean 
	public PasswordEncoder getPe(){ 
		return new BCryptPasswordEncoder();
	}
}

(2)、编写认证服务实现类

@Service 
public class UserDetailsServiceImpl implements UserDetailsService { 
	@Autowired 
	private PasswordEncoder encoder; 
	@Override
	public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException { 
		//1. 查询数据库判断用户名是否存在,如果不存在抛出相应异常 		
		if(!username.equals("admin")){ throw new UsernameNotFoundException("用户名不存在"); 
		} 
		//把查询出来的密码进行解析,或直接把 password 放到构造方法中。 					    
		//理解:password 就是数据库中查询出来的密码,查询出来的内容不是 123 
		String password = encoder.encode("123"); 
		return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); 
		}
}

(3)、自定义登陆成功、失败处理器

1、编写一个控制器类实现AuthenticationSuccessHandler 接口
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override 
	public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException 
	{ 
		//Principal 主体,存放了登录用户的信息 
		User user = (User)authentication.getPrincipal(); 
		System.out.println(user.getUsername()); 
		System.out.println(user.getPassword());//密码输出为 null 
		System.out.println(user.getAuthorities()); //重定向到百度。这只是一个示例,具体需要看项目业务需求 
		httpServletResponse.sendRedirect("http://www.baidu.com");
	 }
}
2、编写一个控制器类实现AuthenticationFailureHandler 接口
public class MyForwardAuthenticationFailureHandler implements AuthenticationFailureHandler { 
	@Override 
	public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,AuthenticationException e) throws IOException, ServletException { 
		httpServletResponse.sendRedirect("/fail.html"); 
	}
}
3、配置设置
http.formLogin() 
.loginProcessingUrl("/login") //当发现/login 时认为是登录,需 要执行UserDetailsServiceImpl 
.successHandler(new MyAuthenticationSuccessHandler()) 
//.successForwardUrl("/toMain") //此处是 post 请求 
.failureHandler(new MyForwardAuthenticationFailureHandler()) 
// .failureForwardUrl("/fail") //登录失败跳转地址
.loginPage("/login.html");

三、权限和角色控制

1、匹配规则

(1)、anyRequest()
.anyRequest().authenticated();
(2)、antMatcher()
public C antMatchers(String... antPatterns)

参数是不定向参数,每个参数是一个 ant 表达式,用于匹配 URL 规则规则如下:
? 匹配一个字符
*匹配 0 个或多个字符
** 匹配 0 个或多个目录

.antMatchers("/js/**").permitAll()
.antMatchers("/**/*.js").permitAll()
(3)、regexMatchers()

使 用 正 则 表 达 式 进 行 匹 配 。 和 antMatchers() 主 要 的 区 别 就 是 参 数 ,
antMatchers()参数是 ant 表达式,regexMatchers()参数是正则表达式。

.regexMatchers(".+[.]js").permitAll()
(4)、mvcMatchers()

mvcMatchers()适用于配置了 servletPath 的情况。servletPath 就是所有的
URL 的 统 一 前 缀 。 在 SpringBoot 整 合 SpringMVC 的 项 目 中 可 以 在
application.properties 中添加下面内容设置 ServletPath。

spring.mvc.servlet.path= /etc

在 Spring Security 的配置类中配置.servletPath()是 mvcMatchers()返回值特有的方法,antMatchers()和 regexMatchers()没有这个方法。在 servletPath()
中 配 置 了 servletPath 后 , mvcMatchers() 直 接 写 SpringMVC 中@RequestMapping()中设置的路径即可。

.mvcMatchers("demo").servletPath("/etc").permitAll()

如果不习惯使用 mvcMatchers()也可以使用 antMatchers(),下面代码和上面代码是等效的

.antMatchers("/etc/demo").permitAll()

2、url权限控制

permitAll()

permitAll()表示所匹配的URL任何人都允许访问。

authenticated()

authenticated()表示所匹配的URL需要被认证才能访问。

anonymous()

anonymous()表示可以匿名访问匹配的URL。和permitAll()效果类似,对于匿名访问的用户,Spring Security支持为其建立一个匿名AnonymousAuthenticationToken存放在SecurityContextHolder中,这就是所谓的匿名认证。这样在以后进行权限认证或者做其它操作时我们就不需要再判断SecurityContextHolder中持有的Authentication对象是否为null了,而直接把它当做一个正常的Authentication进行使用就OK了。

denyAll()

denyAll()表示所匹配的URL 都不允许被访问。

rememberMe()

被“remember me”的用户允许访问。

fullyAuthenticated()

用户通过正常登录认证的而不是被remember me 的,才可以访问。

3、根据权限控制

hasAuthority(String)

判断用户是否具有特定的权限,用户的权限是在自定义登录逻辑中创建 User 对象时指定的。下图中 admin 就是用户的权限。admin 严格区分大小写。

.antMatchers("/main1.html").hasAuthority("admin")
hasAnyAuthority(String …)

如果用户具备给定权限中某一个,就允许访问。下面代码中由于大小写和用户的权限不相同,所以用户无权访问/main1.htm

.antMatchers("/main1.html").hasAnyAuthority("adMin","admiN")

4、根据角色控制

hasRole(String)

如果用户具备给定角色就允许访问。否则出现 403。
参数取值来源于自定义登录逻辑 UserDetailsService 实现类中创建 User 对象时给 User 赋予的授权。
在给用户赋予角色时角色需要以:ROLE_ 开头,后面添加角色名称。例如:
ROLE_abc 其中 abc 是角色名,ROLE_是固定的字符开头。使用 hasRole()时参数也只写 abc 即可。否则启动报错。

.antMatchers("/main1.html").hasRole("abc")
hasAnyRole(String …)

如果用户具备给定角色的任意一个,就允许被访问

四、自定义异常处理

实现AccessDeniedHandler 接口

@Component 
public class MyAccessDeniedHandler implements AccessDeniedHandler {
	@Override 
	public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException 
	{ 
		//设置响应状态码 403
 	httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
  	httpServletResponse.setHeader("Content-Type","application/json;charse t=utf-8") ;
	PrintWriter out = httpServletResponse.getWriter();
	out.write("{\"status\":\"error\",\"msg\":\"权限不足,请联系管理 员!\"}"); 
	out.flush(); 
	out.close();
}

修改配置

http.exceptionHandling() 
.accessDeniedHandler(myAccessDeniedHandler);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值