spring security
- 引入依赖
<!-- spring-security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- jsp面可能会用到标签<security:authentication property="principal.username"/>获取登录用户名 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
- 配置文件application-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<!-- 放行静态资源、登录界面、注册界面 -->
<security:http pattern="/index.jsp" security="none"></security:http>
<security:http pattern="/pages/register.jsp" security="none"></security:http>
<!-- <security:http pattern="/cn/itcast/controller/CategoryController.java"></security:http>-->
<!-- <security:http pattern="/category/register"></security:http>-->
<!-- 配置 -->
<security:http auto-config="false" use-expressions="false">
<!--拦截所有资源,允许ROLE_ADMIN权限通过-->
<intercept-url pattern="/**" access="ROLE_ADMIN"></intercept-url>
<!--配置登录界面、登录url、登录反馈 (/开头) -->
<form-login login-page="/index.jsp"
login-processing-url="/login"
default-target-url="/pages/success.jsp"
authentication-failure-url="/pages/error.jsp"></form-login>
<!-- 退出设置 (/开头) -->
<logout invalidate-session="true" logout-success-url="/index.jsp" logout-url="/logout"></logout>
<!--关闭跨站访问,不关闭会出现拒绝访问-->
<security:csrf disabled="true"></security:csrf>
<!-- 处理框架页 -->
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
</security:http>
<security:authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder"></password-encoder>
<!-- <user-service>-->
<!-- 临时认证用户{noop}不加密 -->
<!-- <user name="admin" authorities="ROLE_ADMIN" password="{noop}admin"></user>-->
<!-- </user-service>-->
</authentication-provider>
</security:authentication-manager>
</beans:beans>
认证类
@Service(value = "userService")
public class SysUserService implements UserService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
//角色权限集合
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
SysUser sysUser = userDao.findByUsername(s);
if (sysUser!=null){
// {noop}表示对密码不加密,采用明文密码
// User user= new User(sysUser.getUname(),"{noop}"+sysUser.getPassword(),grantedAuthorities);
// 对密码加密
User user= new User(sysUser.getUname(),sysUser.getPassword(),grantedAuthorities);
return user;
}
return null;
}
public interface UserService extends UserDetailsService {
public void save(SysUser user);
}
在applicationContext.xml配置加密类:
<!--spring-security自带加密类:MD5加密 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
web.xml配置
<!--全局参数:指定配置文件的路径,加载所有配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/application*.xml</param-value>
</context-param>
<!--spring-security配置-->
<!--配置委派代理过滤器: filter-name必须是:springSecurityFilterChain -->
<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>
- 获取登录名
后台获取
@RequestMapping("/username")
public @ResponseBody String test(HttpServletRequest request){
//通过SecurityContextHolder获得当前线程上绑定的SecurityContext对象
SecurityContext securityContext = SecurityContextHolder.getContext();
//也可以通过session获得SecurityContext对象
// SecurityContext context_session = (SecurityContext) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
// 获得认证对象
Authentication authentication = securityContext.getAuthentication();
// 获得用户
User user = (User) authentication.getPrincipal();
// 获取用户名
String username = user.getUsername();
System.out.println(username);
return username;
}
jsp页面显示登录名
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
当前登录名方法一:${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.username}<br>
当前登录名方法二:
当前用户名:<security:authentication property="principal.username"/>
- 针对不同权限的用户设置访问不同资源
在jsp页面控制,这样不同权限的用户显示不同的内容
<%--引入安全框架标签--%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
<%--只有ROLE_ADMIN权限的用户能看到--%>
<security:authorize access="hasRole('ROLE_ADMIN')">
<form action="/login" method="post">
用户名<input type="text" name="username"><br>
密码<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</security:authorize>
<%--拥有ROLE_ADMIN、ROLE_USER权限均可以看到--%>
<security:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_USER')">
<form action="/category/show">
用户名<input type="text" name="cid"><br>
密码<input type="text" name="cname"><br>
<input type="submit" value="登录">
</form>
</security:authorize>
由于在页面access=hasAnyRole()使用了表达式所以需要修改application-security.xml, 改为:use-expression = “true”
<security:http auto-config="false" use-expressions="true">
controller 服务端访问权限控制:不同权限访问不同方法
控制方式就是借助于Spring的AOP,对Controller的的访问进行权限的功能增强。 修改application-mvc.xml配置文 件,添加aop的自定代理
<!--aop的自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--配置开启security的注解支持-->
<security:global-method-security secured-annotations="enabled"/>
在controller方法上添加@Secured()注解
@Controller
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@Autowired
private UserService userService;
@RequestMapping("/show")
@Secured({"ROLE_ADMIN","ROLE_USER"})
public ModelAndView showAll( Category category){
System.out.println(category);
List<Category> categories = categoryService.findAll();
if (categories==null){
System.out.println("null");
}else {
System.out.println("not null");
}
ModelAndView model = new ModelAndView();
model.setViewName("showData");
model.addObject("categoryList",categories);
return model;
}
问题
6. 当配置文件的scame版本,与引入依赖版本有关。当不匹配时会报类似的错误:org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema with Spring Security 4.2. Please update your schema declarations to the 4.2 schema.
7. 使用spring security 安全框架会导致注册请求也被拦截,因此要放行注册请求的controller 方法。具体怎么做待解决。
8. spring security 配置文件配置总结
模块 | 示例 |
---|---|
登录页设置 | security:http</security:http> 登录、登出、跨域、框架页处理 |
静态资源放行 | security:http</security:http> |
认证管理器 | security:authentication-manager</security:authentication-manager> |
认证类编写 | extends UserDetailsService |
来源:CSDN
作者:GeXueliu
链接:https://blog.csdn.net/GeXueliu/article/details/103487149