Spring Security是什么?
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
对于安全控制,我们仅需引入spring-boot-starter-security模块,进行少量的配置,就可实现强大的安全管理(这是百度的,简介了说白了就一个安全框架和shiro一类的东西,提高网站的安全性)。
在我看来就是项目中加入和很多拦截,使得我们不能通过拼项目路径就能够访问系统内部的一些资源。
如何使用的它
1.首先要添加它的Jar包,或者Maven依赖
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<spring.security.version>5.0.1.RELEASE</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.要加载核心的配置类,在web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-security.xml</param-value>
</context-param>
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<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>
springSecurityFilterChain 据说这个东西很重要哈!!!貌似就是注册过滤器的一个代理类。springSecurity中有很多Filter,这个类就负责将其它的类都注册。只要配置这一个类。基本上springSecurity就可以使用了。(一了百了)。
3.编写配置文件spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不过滤的资源(静态资源及登录相关) -->
<security:http security="none" pattern="/login.jsp" />
<security:http security="none" pattern="/failer.jsp" />
<security:http security="none" pattern="/css/**" />
<security:http security="none" pattern="/img/**" />
<security:http security="none" pattern="/plugins/**" />
<security:http auto-config="true" use-expressions="false">
<!-- 配置资料连接,表示任意路径都需要ROLE_USER权限 -->
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN" />
<!-- 自定义登陆页面,login-page 自定义登陆页面 authentication-failure-url 用户权限校验失败之
后才会跳转到这个页面,如果数据库中没有这个用户则不会跳转到这个页面。
default-target-url 登陆成功后跳转的页面。 注:登陆页面用户名固定 username,密码
password,action:login -->
<security:form-login login-page="/login.jsp"
login-processing-url="/login.do"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
default-target-url="/index.jsp"
/>
<!-- 登出, invalidate-session 是否删除session logout-url:登出处理链接 logout-success-
url:登出成功页面
注:登出操作 只需要链接到 logout即可登出当前用户 -->
<security:logout invalidate-session="true" logout-url="/logout.do"
logout-success-url="/login.jsp" />
<!-- 关闭CSRF,默认是开启的 -->
<security:csrf disabled="true" />
</security:http>
<!--授权-->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密类 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
</beans>
这个配置文件中有几个重要的地方。
登录
正常情况下,我们是通过登录界面点击提交–>controller–>service(验证密码)–>dao(成功后提交跳转到主页)。
但是在spring-security中是不同的。这里不需要controller。直接通过login.jsp页面请求service在service来实现具体的认证授权。
请求到service 这个过程已经在配置文件中明确的写好了
<security:form-login login-page="/login.jsp"
login-processing-url="/login.do"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
default-target-url="/index.jsp"
/>
这里就是登录的页面,失败跳到哪里。成功之后跳到哪里。
当你从login.jsp页面填好用户名:密码:后user-service-ref=“userService”
明确了它会调用userSerivice
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
UserService接口
public interface IUserService extends UserDetailsService {
}
实现类
点击登陆后根据配置文件直接调用service 根据用户名向数据库中查找用户信息然后密码校验。
这里spring-security它提供了我们一个User类。
当密码校验成功后我们调用,User的构造方法。
将 用户名,密码,用户拥有的角色添加进去就可以了。
这里就是类的部分内容
public class User implements UserDetails, CredentialsContainer {
private static final long serialVersionUID = 500L;
private String password;
private final String username;
private final Set<GrantedAuthority> authorities;
private final boolean accountNonExpired;
private final boolean accountNonLocked;
private final boolean credentialsNonExpired;
private final boolean enabled;
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
这个类里面有几个难点,比如User构造方法的参数
第一个用户名,这个没什么说的。
第二个密码,这里是不加密的方式校验。{noop}这个前缀就是不加密的前缀。
第三个:用户的角色拥有的角色。这个参数类型是个集合。
ArrayList list = new ArrayList<>();
将用户所拥有的角色添加到这个集合中,然后去和配置文件中的角色进行对比。
<security:intercept-url pattern="/**" access=“ROLE_USER,ROLE_ADMIN”/>
这个地方就是配置的角色信息。要想访问系统,必须用户要具有这两个角色。否则会进行拦截。
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo=null;
try {
userInfo = userDao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getRoles(userInfo.getRoles()));
return user;
}
//将角色拼接成合法的
public List<SimpleGrantedAuthority> getRoles(List<Role> roles){
ArrayList<SimpleGrantedAuthority> list = new ArrayList<>();
for(Role r: roles){
list.add(new SimpleGrantedAuthority("ROLE_"+r));
}
return list;
}
}
这就是它最最最基本的使用
这个东西不简单啊!!!对于我来说太难了。
不过慢慢来把!!!
加油!!!