- 什么是spring-security?
- 我们能用spring-security做什么?
- spring-security 入门案例
- spring-security需要注意的点
1、什么是spring-security? spring-security解决系统安全问题的框架,sprign-security 是spring家族里面的一员,完美结合spring,充分利用了spring ico和aop等功能 想了解为什么我们要用springSecurity可以看一下这个文章 为什么越来越多程序员使用SpringSecurity,这些原因你都知道吗?
2、我们能用spring-security做什么? 我们可以利用spring-security进行权限控制,比如我想让这个输入框或者按钮只让管理员才可以看到,spring-security可以做到这些spring-security 按钮级权限控制
3、spring-security 入门案例 我个人觉得先把ssm的搞懂了在去弄springboot会好一点 案例我分两个讲吧,一个是不依赖数据库写死的用户权限让小白更好的理解,第二个是依赖数据库做用户权限 不依赖数据库 spring-security 的依赖坐标
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
springSecurity.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 pattern="/index.html" security="none"/>
<security:http auto-config="true" use-expressions="false">
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page="/index.html"
login-processing-url="/upload/logInTest"
authentication-failure-handler-ref="failureHandler"
authentication-success-handler-ref="successHandler"/>
<security:csrf disabled="true"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="user"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="successHandler" class="com.ownCloud.main.security.SuccessHandler"></bean>
<bean id="failureHandler" class="com.ownCloud.main.security.FailureHandler"></bean>
</beans>
web.xml
<web-app>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:ApplicationContext.xml,
classpath:springSecurity.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
</web-app>
以下就是相关代码: index.html
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<form action="/upload/logInTest" method="post">
<span>用户名:</span><input type="text" id="username" name="username"/>
<span>密码:</span><input type="password" id="password" name="password"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
SuccessHandler.class
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;
public class SuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
System.out.println(httpServletResponse.getWriter().toString());
}
}
FailureHandler.class
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
System.out.println(e.toString());
}
}
4、spring-security需要注意的点 在编写配置文件时需要注意的点: 1、放行你需要的资源,如果不配置则登录页面会说重定向过多,那是因为你的页面被spring-security 拦截了,由于是拦截所以不会报错404,由于被拦截浏览器会重试,然后就是死循环
<security:http pattern="/index.html" security="none"/>
因为我们在拦截资源那里配置了拦截资源范围,写的是"/**"这代表拦截所有资源
2、表单(form)中input的属性名(name) 你们可能会好奇spring-security是怎么获取我表单中用户名和密码的,这里要说明spring-security中form表单中识别用户名和密码属性名默认为"username"和"password" 当然spring-security不只可以表单验证,感兴趣的小伙伴可以去看看 spring-security 验证
3、关闭跨域请求,不然会跨域错误
<security:csrf disabled="true"/>
那我springSecurity.xml写好了,怎么才能让spring读到呢? 我们需要配置web.xml 让spring知道我们有一个文件需要它读取,别忘了spring是一个容器,既然是容器就把东西往里丢就可以了 4、springSecurity依赖版本问题 springSecurity 4点几的版本往上你输入的密码会被自动加密,你在验证密码的时候需要解码,这里我使用的是4.1.0的版本 依赖数据库 springSecurity.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 pattern="/index.html" security="none"/>
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:form-login login-page="/index.html"
login-processing-url="/upload/logInTest"
authentication-failure-handler-ref="failureHandler"
authentication-success-handler-ref="successHandler"/>
<security:csrf disabled="true"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="UserServiceImp">
</security:authentication-provider>
</security:authentication-manager>
<bean id="successHandler" class="com.ownCloud.main.security.SuccessHandler"></bean>
<bean id="failureHandler" class="com.ownCloud.main.security.FailureHandler"></bean>
</beans>
依赖数据库主要是需要实现一个springSecurity的User接口
<security:authentication-provider user-service-ref="UserServiceImp">
当然你实现的接口需要被spring管理如:“UserServiceImp” UserService 需要继承UserDetailsService类
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UserService extends UserDetailsService {
}
而UserServiceImp 实现UserService
import com.ownCloud.main.dao.UserDao;
import com.ownCloud.main.dao.entity.UserEntity;
import com.ownCloud.main.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service(value = "UserServiceImp")
public class UserServiceImp implements UserService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
UserEntity userEntity =null;
try {
userEntity = userDao.queryUserByUsername(s);
}catch (Exception e){
e.printStackTrace();
}
if (!Objects.isNull(userEntity)) {
return new User(userEntity.getUsername(), userEntity.getPassword(), getAuthority());
}else {
return null;
}
}
public List<SimpleGrantedAuthority> getAuthority(){
List<SimpleGrantedAuthority> list=new ArrayList<>();
list.add(new SimpleGrantedAuthority("ROLE_USER"));
return list;
}
}
UserEntity 需要实现 UserDetails类
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class UserEntity implements UserDetails {
String username;
char gender;
String passWord;
Integer age;
String phoneNumber;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return passWord;
}
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
public void setUsername(String username) {
this.username = username;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
这样依赖数据库的所有配置就都完成了,还有不懂的可以私信我
|