目录
1、环境搭建
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<filter>
<!--
DelegatingFilterProxy用于整合第三方框架
整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
否则会抛出NoSuchBeanDefinitionException异常
-->
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!--
http:用于定义相关权限控制
auto-config:是否自动配置
设置为true时框架会提供默认的一些配置,例如提供默认的登录页面、登出处理等
设置为false时需要显示提供登录表单配置,否则会报错
use-expressions:用于指定intercept-url中的access属性是否使用表达式
-->
<security:http auto-config="true" use-expressions="true">
<!--
intercept-url:定义一个拦截规则
pattern:对哪些url进行权限控制
access:在请求对应的URL时需要什么权限,默认配置时它应该是一个以逗号分隔的角色列表,
请求的用户只需拥有其中的一个角色就能成功访问对应的URL
-->
<security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
</security:http>
<!--authentication-manager:认证管理器,用于处理认证操作-->
<security:authentication-manager>
<!--authentication-provider:认证提供者,执行具体的认证逻辑-->
<security:authentication-provider>
<!--user-service:用于获取用户信息,提供给authentication-provider进行认证-->
<security:user-service>
<!--
user:定义用户信息,可以指定用户名、密码、角色,后期可以改为从数据库查询用户信息
{noop}:表示当前使用的密码为明文
-->
<security:user name="admin"
password="{noop}admin"
authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
2、匿名访问
<security:http security="none" pattern="/pages/a.html" />
<security:http security="none" pattern="/pages/b.html" />
访问a、b页面不用再跳转到默认登录页面
3、指定自定义的登录页面
4、从数据库查询信息
package com.health.security;
import com.health.pojo.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SpringSecurityUserService implements UserDetailsService {
public static Map<String, User> map = new HashMap<>();
static{
User user1 = new User();
user1.setUsername("aa");
user1.setPassword("123");
User user2 = new User();
user2.setUsername("bb");
user2.setPassword("123");
map.put(user1.getUsername(),user1);
map.put(user2.getUsername(),user2);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = map.get(username);
if(user == null){
return null;
}else{
//存储权限
List<GrantedAuthority> list = new ArrayList<>();
//授权
list.add(new SimpleGrantedAuthority("permission_A"));
list.add(new SimpleGrantedAuthority("permission_B"));
//授予角色:
if(username.equals("aa")){
list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
org.springframework.security.core.userdetails.User securityUser
= new org.springframework.security.core.userdetails.User(username,"{noop}"+user.getPassword(),list);
return securityUser;
}
}
}
aa可以访问,bb不可以
5、密码加密
package com.health.security;
import com.health.pojo.User;
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.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SpringSecurityUserService implements UserDetailsService {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public Map<String, User> map = new HashMap<>();
public void initMap(){
User user1 = new User();
user1.setUsername("aa");
user1.setPassword(passwordEncoder.encode("123"));
User user2 = new User();
user2.setUsername("bb");
user2.setPassword(passwordEncoder.encode("123"));
map.put(user1.getUsername(),user1);
map.put(user2.getUsername(),user2);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
initMap();
User user = map.get(username);
if(user == null){
return null;
}else{
System.out.println(user.getPassword());
//存储权限
List<GrantedAuthority> list = new ArrayList<>();
//授权
list.add(new SimpleGrantedAuthority("permission_A"));
list.add(new SimpleGrantedAuthority("permission_B"));
//授予角色:
if(username.equals("aa")){
list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
org.springframework.security.core.userdetails.User securityUser
= new org.springframework.security.core.userdetails.User(username,user.getPassword(),list);
return securityUser;
}
}
}
6、多种校验规则
<!--只要认证通过就可以访问-->
<security:intercept-url pattern="/pages/a.html" access="isAuthenticated()" />
<security:intercept-url pattern="/index.html" access="isAuthenticated()" />
<!--拥有add权限就可以访问b.html页面-->
<security:intercept-url pattern="/pages/b.html" access="hasAuthority('add')" />
<!--拥有ROLE_ADMIN角色就可以访问c.html页面-->
<security:intercept-url pattern="/pages/c.html" access="hasRole('ROLE_ADMIN')" />
<!--拥有ROLE_ADMIN角色就可以访问d.html页面,
注意:此处虽然写的是ADMIN角色,框架会自动加上前缀ROLE_-->
<security:intercept-url pattern="/pages/d.html" access="hasRole('ADMIN')" />
7、注解方式控制权限
package com.health.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class SecurityController {
@RequestMapping("/add")
@PreAuthorize("hasAnyAuthority('add')")//表示用户必须拥有add权限才能调用当前方法
public String add(){
System.out.println("add...");
return "addsuccess";
}
@RequestMapping("/delete")
@PreAuthorize("hasRole('ROLE_ADMIN')")//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法
public String delete(){
System.out.println("delete...");
return "deletesuccess";
}
}
可以访问delete,由于没有add权限,不可访问add