https://blog.csdn.net/it_java_shuai/article/details/78054951

Spring Security和Shiro的比较和使用

2017年09月21日 17:47:37

阅读数:7321

这个文章是我找了几个博客总结到一块成为这个文章。

首先,先说比较吧!

这个博客地址是:http://www.cnblogs.com/aoeiuv/p/5868128.html

Shiro

首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。

Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。如下是它所具有的特点:

  1. 易于理解的 Java Security API;
  2. 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
  3. 对角色的简单的签权(访问控制),支持细粒度的签权;
  4. 支持一级缓存,以提升应用程序的性能;
  5. 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;
  6. 异构客户端会话访问;
  7. 非常简单的加密 API;
  8. 不跟任何的框架或者容器捆绑,可以独立运行。

Spring Security

除了不能脱离Spring,shiro的功能它都有。而且Spring Security对Oauth、OpenID也有支持,Shiro则需要自己手动实现。Spring Security的权限细粒度更高(笔者还未发现高在哪里)。

注:

OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。

OpenID 系统的第一部分是身份验证,即如何通过 URI 来认证用户身份。目前的网站都是依靠用户名和密码来登录认证,这就意味着大家在每个网站都需要注册用户名和密码,即便你使用的是同样的密码。如果使用 OpenID ,你的网站地址(URI)就是你的用户名,而你的密码安全的存储在一个 OpenID 服务网站上(你可以自己建立一个 OpenID 服务网站,也可以选择一个可信任的 OpenID 服务网站来完成注册)。

与OpenID同属性的身份识别服务商还有ⅥeID,ClaimID,CardSpace,Rapleaf,Trufina ID Card等,其中ⅥeID通用账户的应用最为广泛。

综述

个人认为现阶段需求,权限的操作粒度能控制在路径及按钮上,数据粒度通过sql实现。Shrio简单够用。

至于OAuth,OpenID 站点间统一登录功能,现租户与各个产品间单点登录已经通过cookies实现,所以Spring Security的这两个功能可以不考虑。

SpringSide网站的权限也是用Shrio做的。

---------------------------------------------------------------------------------------------------------------------

接着我们来说shiro的使用吧!

源博客地址是:http://peirenlei.iteye.com/blog/2086639

---------------------------------------------------------------------------------------------------------------------

我们采用下面的逻辑创建权限表结构(不是绝对的,根据需要修改)

一个用户可以有多种角色(normal,manager,admin等等)
一个角色可以有多个用户(user1,user2,user3等等)
一个角色可以有多个权限(save,update,delete,query等等)
一个权限只属于一个角色(delete只属于manager角色)

我们创建四张表:
t_user用户表:设置了3个用户
-------------------------------
id + username   + password
---+----------------+----------
1  +   tom           +  000000
2  +   jack           +  000000
3  +   rose          +  000000
---------------------------------
t_role角色表:设置3个角色
--------------
id + rolename 
---+----------
1  + admin
2  + manager
3  + normal
--------------
t_user_role用户角色表:tom是admin和normal角色,jack是manager和normal角色,rose是normal角色
---------------------
user_id  +  role_id
-----------+-----------
1            +     1
1            +     3
2            +     2
2            +     3
3            +     3
---------------------
t_permission权限表:admin角色可以删除,manager角色可以添加和更新,normal角色可以查看
-----------------------------------
id  +  permissionname  +  role_id
----+------------------------+-----------
1   +   add                     +     2
2   +   del                       +    1
3   +   update                +     2
4   +   query                   +    3
-----------------------------------

 建立对应的POJO:

  1. package com.cn.pojo;
  2. import java.util.HashSet;
  3. import java.util.List;
  4. import java.util.Set;
  5. import javax.persistence.Entity;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.JoinTable;
  11. import javax.persistence.ManyToMany;
  12. import javax.persistence.Table;
  13. import javax.persistence.Transient;
  14. import org.hibernate.validator.constraints.NotEmpty;
  15. @Entity
  16. public class User {
  17. private Integer id;
  18. @NotEmpty(message="用户名不能为空")
  19. private String username;
  20. @NotEmpty(message="密码不能为空")
  21. private String password;
  22. private List<Role> roleList;//一个用户具有多个角色
  23. @Id
  24. @GeneratedValue(strategy=GenerationType.IDENTITY)
  25. public Integer getId() {
  26. return id;
  27. public void setId(Integer id) {
  28. this.id = id;
  29. public String getUsername() {
  30. return username;
  31. public void setUsername(String username) {
  32. this.username = username;
  33. public String getPassword() {
  34. return password;
  35. public void setPassword(String password) {
  36. this.password = password;
  37. @ManyToMany
  38. @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="user_id")},inverseJoinColumns={@JoinColumn(name="role_id")})
  39. public List<Role> getRoleList() {
  40. return roleList;
  41. public void setRoleList(List<Role> roleList) {
  42. this.roleList = roleList;
  43. @Transient
  44. public Set<String> getRolesName(){
  45. Set<String> set=new HashSet<String>();
  46. for (Role role : roles) {
  47. }
  48. return set;
  49. }
  1. package com.cn.pojo;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import javax.persistence.Entity;
  5. import javax.persistence.GeneratedValue;
  6. import javax.persistence.GenerationType;
  7. import javax.persistence.Id;
  8. import javax.persistence.JoinColumn;
  9. import javax.persistence.JoinTable;
  10. import javax.persistence.ManyToMany;
  11. import javax.persistence.OneToMany;
  12. import javax.persistence.Table;
  13. import javax.persistence.Transient;
  14. @Entity
  15. public class Role {
  16. private Integer id;
  17. private String rolename;
  18. private List<Permission> permissionList;//一个角色对应多个权限
  19. private List<User> userList;//一个角色对应多个用户
  20. @Id
  21. @GeneratedValue(strategy=GenerationType.IDENTITY)
  22. public Integer getId() {
  23. return id;
  24. public void setId(Integer id) {
  25. this.id = id;
  26. public String getRolename() {
  27. return rolename;
  28. public void setRolename(String rolename) {
  29. this.rolename = rolename;
  30. @OneToMany(mappedBy="role")
  31. public List<Permission> getPermissionList() {
  32. return permissionList;
  33. public void setPermissionList(List<Permission> permissionList) {
  34. this.permissionList = permissionList;
  35. @ManyToMany
  36. @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="role_id")},inverseJoinColumns={@JoinColumn(name="user_id")})
  37. public List<User> getUserList() {
  38. return userList;
  39. public void setUserList(List<User> userList) {
  40. this.userList = userList;
  41. @Transient
  42. public List<String> getPermissionsName(){
  43. new ArrayList<String>();
  44. for (Permission per : perlist) {
  45. }
  46. return list;
  47. }
  1. package com.cn.pojo;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.JoinColumn;
  7. import javax.persistence.ManyToOne;
  8. import javax.persistence.Table;
  9. @Entity
  10. public class Permission {
  11. private Integer id;
  12. private String permissionname;
  13. private Role role;//一个权限对应一个角色
  14. @Id
  15. @GeneratedValue(strategy=GenerationType.IDENTITY)
  16. public Integer getId() {
  17. return id;
  18. public void setId(Integer id) {
  19. this.id = id;
  20. public String getPermissionname() {
  21. return permissionname;
  22. public void setPermissionname(String permissionname) {
  23. this.permissionname = permissionname;
  24. @ManyToOne
  25. @JoinColumn(name="role_id")
  26. public Role getRole() {
  27. return role;
  28. public void setRole(Role role) {
  29. this.role = role;
  30. }

使用SHIRO的步骤:
1,导入jar
2,配置web.xml
3,建立dbRelm
4,在Spring中配置

pom.xml中配置如下:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>com.hyx</groupId>
  5. <artifactId>springmvc</artifactId>
  6. <packaging>war</packaging>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <name>springmvc Maven Webapp</name>
  9. <url>http://maven.apache.org</url>
  10. <dependencies>
  11. <dependency>
  12. <groupId>junit</groupId>
  13. <artifactId>junit</artifactId>
  14. <version>3.8.1</version>
  15. <scope>test</scope>
  16. </dependency>
  17. <!-- SpringMVC核心jar -->
  18. <dependency>
  19. <groupId>org.springframework</groupId>
  20. <artifactId>spring-webmvc</artifactId>
  21. <version>3.2.4.RELEASE</version>
  22. </dependency>
  23. <!-- springmvc连接数据库需要的jar -->
  24. <dependency>
  25. <groupId>org.springframework</groupId>
  26. <artifactId>spring-jdbc</artifactId>
  27. <version>3.2.4.RELEASE</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework</groupId>
  31. <artifactId>spring-orm</artifactId>
  32. <version>3.2.4.RELEASE</version>
  33. </dependency>
  34. <!-- ************************************ -->
  35. <!-- Hibernate相关jar -->
  36. <dependency>
  37. <groupId>org.hibernate</groupId>
  38. <artifactId>hibernate-core</artifactId>
  39. <version>4.2.5.Final</version>
  40. </dependency>
  41. <dependency>
  42. <groupId>org.hibernate</groupId>
  43. <artifactId>hibernate-ehcache</artifactId>
  44. <version>4.2.5.Final</version>
  45. </dependency>
  46. <dependency>
  47. <groupId>net.sf.ehcache</groupId>
  48. <artifactId>ehcache</artifactId>
  49. <version>2.7.2</version>
  50. </dependency>
  51. <dependency>
  52. <groupId>commons-dbcp</groupId>
  53. <artifactId>commons-dbcp</artifactId>
  54. <version>1.4</version>
  55. </dependency>
  56. <dependency>
  57. <groupId>mysql</groupId>
  58. <artifactId>mysql-connector-java</artifactId>
  59. <version>5.1.26</version>
  60. </dependency>
  61. <!-- javax提供的annotation -->
  62. <dependency>
  63. <groupId>javax.inject</groupId>
  64. <artifactId>javax.inject</artifactId>
  65. <version>1</version>
  66. </dependency>
  67. <!-- **************************** -->
  68. <!-- hibernate验证 -->
  69. <dependency>
  70. <groupId>org.hibernate</groupId>
  71. <artifactId>hibernate-validator</artifactId>
  72. <version>5.0.1.Final</version>
  73. </dependency>
  74. <!-- 用于对@ResponseBody注解的支持 -->
  75. <dependency>
  76. <groupId>org.codehaus.jackson</groupId>
  77. <artifactId>jackson-mapper-asl</artifactId>
  78. <version>1.9.13</version>
  79. </dependency>
  80. <!-- 提供对c标签的支持 -->
  81. <dependency>
  82. <groupId>javax.servlet</groupId>
  83. <artifactId>jstl</artifactId>
  84. <version>1.2</version>
  85. </dependency>
  86. <!-- servlet api -->
  87. <dependency>
  88. <groupId>javax.servlet</groupId>
  89. <artifactId>servlet-api</artifactId>
  90. <version>2.5</version>
  91. </dependency>
  92. <!--Apache Shiro所需的jar包-->
  93. <dependency>
  94. <groupId>org.apache.shiro</groupId>
  95. <artifactId>shiro-core</artifactId>
  96. <version>1.2.2</version>
  97. </dependency>
  98. <dependency>
  99. <groupId>org.apache.shiro</groupId>
  100. <artifactId>shiro-web</artifactId>
  101. <version>1.2.2</version>
  102. </dependency>
  103. <dependency>
  104. <groupId>org.apache.shiro</groupId>
  105. <artifactId>shiro-spring</artifactId>
  106. <version>1.2.2</version>
  107. </dependency>
  108. </dependencies>
  109. <build>
  110. <finalName>springmvc</finalName>
  111. <!-- maven的jetty服务器插件 -->
  112. <plugins>
  113. <plugin>
  114. <groupId>org.mortbay.jetty</groupId>
  115. <artifactId>jetty-maven-plugin</artifactId>
  116. <configuration>
  117. <scanIntervalSeconds>10</scanIntervalSeconds>
  118. <webApp>
  119. <contextPath>/</contextPath>
  120. </webApp>
  121. <!-- 修改jetty的默认端口 -->
  122. <connectors>
  123. <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
  124. <port>80</port>
  125. <maxIdleTime>60000</maxIdleTime>
  126. </connector>
  127. </connectors>
  128. </configuration>
  129. </plugin>
  130. </plugins>
  131. </build>
  132. </project>

 web.xml中的配置:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <web-app version="2.5"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. >
  7. <display-name>Archetype Created Web Application</display-name>
  8. <!-- spring-orm-hibernate4的OpenSessionInViewFilter -->
  9. <filter>
  10. <filter-name>opensessioninview</filter-name>
  11. <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
  12. </filter>
  13. <filter-mapping>
  14. <filter-name>opensessioninview</filter-name>
  15. <url-pattern>/*</url-pattern>
  16. </filter-mapping>
  17. <!-- 配置springmvc servlet -->
  18. <servlet>
  19. <servlet-name>springmvc</servlet-name>
  20. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  21. <load-on-startup>1</load-on-startup>
  22. </servlet>
  23. <servlet-mapping>
  24. <servlet-name>springmvc</servlet-name>
  25. <!-- / 表示所有的请求都要经过此serlvet -->
  26. <url-pattern>/</url-pattern>
  27. </servlet-mapping>
  28. <!-- spring的监听器 -->
  29. <context-param>
  30. <param-name>contextConfigLocation</param-name>
  31. <param-value>classpath:applicationContext*.xml</param-value>
  32. </context-param>
  33. <listener>
  34. <listener-class>
  35. </listener-class>
  36. </listener>
  37. <!-- Shiro配置 -->
  38. <filter>
  39. <filter-name>shiroFilter</filter-name>
  40. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  41. </filter>
  42. <filter-mapping>
  43. <filter-name>shiroFilter</filter-name>
  44. <url-pattern>/*</url-pattern>
  45. </filter-mapping>
  46. </web-app>
  1. package com.cn.service;
  2. import java.util.List;
  3. import javax.inject.Inject;
  4. import org.apache.shiro.authc.AuthenticationException;
  5. import org.apache.shiro.authc.AuthenticationInfo;
  6. import org.apache.shiro.authc.AuthenticationToken;
  7. import org.apache.shiro.authc.SimpleAuthenticationInfo;
  8. import org.apache.shiro.authc.UsernamePasswordToken;
  9. import org.apache.shiro.authz.AuthorizationInfo;
  10. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  11. import org.apache.shiro.realm.AuthorizingRealm;
  12. import org.apache.shiro.subject.PrincipalCollection;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import com.cn.pojo.Role;
  16. import com.cn.pojo.User;
  17. @Service
  18. public class MyShiro extends AuthorizingRealm{
  19. @Inject
  20. private UserService userService;
  21. /**
  22. * 权限认证
  23. */
  24. @Override
  25. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  26. //获取登录时输入的用户名
  27. //到数据库查是否有此对象
  28. if(user!=null){
  29. //权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
  30. new SimpleAuthorizationInfo();
  31. //用户的角色集合
  32. //用户的角色对应的所有权限,如果只使用角色定义访问权限,下面的四行可以不要
  33. for (Role role : roleList) {
  34. }
  35. return info;
  36. return null;
  37. /**
  38. * 登录认证;
  39. */
  40. @Override
  41. protected AuthenticationInfo doGetAuthenticationInfo(
  42. throws AuthenticationException {
  43. //UsernamePasswordToken对象用来存放提交的登录信息
  44. //查出是否有此用户
  45. if(user!=null){
  46. //若存在,将此用户存放到登录认证info中
  47. return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
  48. return null;
  49. }

在spring的配置文件中配置,为了区别spring原配置和shiro我们将shiro的配置独立出来。

applicationContext-shiro.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  10. <!-- 配置权限管理器 -->
  11. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  12. <!-- ref对应我们写的realm  MyShiro -->
  13. <property name="realm" ref="myShiro"/>
  14. <!-- 使用下面配置的缓存管理器 -->
  15. <property name="cacheManager" ref="cacheManager"/>
  16. </bean>
  17. <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
  18. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  19. <!-- 调用我们配置的权限管理器 -->
  20. <property name="securityManager" ref="securityManager"/>
  21. <!-- 配置我们的登录请求地址 -->
  22. <property name="loginUrl" value="/login"/>
  23. <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->
  24. <property name="successUrl" value="/user"/>
  25. <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->
  26. <property name="unauthorizedUrl" value="/403"/>
  27. <!-- 权限配置 -->
  28. <property name="filterChainDefinitions">
  29. <value>
  30. <!-- anon表示此地址不需要任何权限即可访问 -->
  31. <!-- perms[user:query]表示访问此连接需要权限为user:query的用户 -->
  32. user=perms[user:query]
  33. <!-- roles[manager]表示访问此连接需要用户的角色为manager -->
  34. add=roles[manager]
  35. /user/edit/**=roles[manager]
  36. <!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login-->
  37. </value>
  38. </property>
  39. </bean>
  40. <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
  41. <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
  42. </beans>

 用于登录,登出,权限跳转的控制:

  1. package com.cn.controller;
  2. import javax.validation.Valid;
  3. import org.apache.shiro.SecurityUtils;
  4. import org.apache.shiro.authc.AuthenticationException;
  5. import org.apache.shiro.authc.UsernamePasswordToken;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.ui.Model;
  8. import org.springframework.validation.BindingResult;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import org.springframework.web.bind.annotation.RequestMethod;
  11. import org.springframework.web.servlet.mvc.support.RedirectAttributes;
  12. import com.cn.pojo.User;
  13. @Controller
  14. public class HomeController {
  15. @RequestMapping(value="/login",method=RequestMethod.GET)
  16. public String loginForm(Model model){
  17. "user", new User());
  18. return "/login";
  19. @RequestMapping(value="/login",method=RequestMethod.POST)
  20. public String login(@Valid User user,BindingResult bindingResult,RedirectAttributes redirectAttributes){
  21. try {
  22. if(bindingResult.hasErrors()){
  23. return "/login";
  24. //使用权限工具进行用户登录,登录成功后跳到shiro配置的successUrl中,与下面的return没什么关系!
  25. new UsernamePasswordToken(user.getUsername(), user.getPassword()));
  26. return "redirect:/user";
  27. catch (AuthenticationException e) {
  28. "message","用户名或密码错误");
  29. return "redirect:/login";
  30. }
  31. @RequestMapping(value="/logout",method=RequestMethod.GET)
  32. public String logout(RedirectAttributes redirectAttributes ){
  33. //使用权限管理工具进行用户的退出,跳出登录,给出提示信息
  34. redirectAttributes.addFlashAttribute("message", "您已安全退出");
  35. return "redirect:/login";
  36. @RequestMapping("/403")
  37. public String unauthorizedRole(){
  38. return "/403";
  39. }

 三个主要的JSP:
login.jsp:

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
  3. >
  4. <html>
  5. <head>
  6. <title>My JSP 'MyJsp.jsp' starting page</title>
  7. </head>
  8. <body>
  9. <h1>登录页面----${message }</h1>
  10. <img alt="" src="/static/img/1.jpg">
  11. <form:form action="/login" commandName="user" method="post">
  12. <form:input path="username"/> <form:errors path="username" cssClass="error"/> <br/>
  13. <form:password path="password"/> <form:errors path="password" cssClass="error" /> <br/>
  14. <form:button name="button">submit</form:button>
  15. </form:form>
  16. </body>
  17. </html>

user.jsp:

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
  4. >
  5. <html>
  6. <head>
  7. <title>用户列表</title>
  8. </head>
  9. <body>
  10. <h1>${message }</h1>
  11. <h1>用户列表--<a href="/user/add">添加用户</a>---<a href="/logout">退出登录</a>    </h1>
  12. <h2>权限列表</h2>
  13. <shiro:authenticated>用户已经登录显示此内容</shiro:authenticated>
  14. <shiro:hasRole name="manager">manager角色登录显示此内容</shiro:hasRole>
  15. <shiro:hasRole name="admin">admin角色登录显示此内容</shiro:hasRole>
  16. <shiro:hasRole name="normal">normal角色登录显示此内容</shiro:hasRole>
  17. <shiro:hasAnyRoles name="manager,admin">**manager or admin 角色用户登录显示此内容**</shiro:hasAnyRoles>
  18. <shiro:principal/>-显示当前登录用户名
  19. <shiro:hasPermission name="add">add权限用户显示此内容</shiro:hasPermission>
  20. <shiro:hasPermission name="user:query">query权限用户显示此内容<shiro:principal/></shiro:hasPermission>
  21. <shiro:lacksPermission name="user:del"> 不具有user:del权限的用户显示此内容 </shiro:lacksPermission>
  22. <ul>
  23. <c:forEach items="${userList }" var="user">
  24. <li>用户名:${user.username }----密码:${user.password }----<a href="/user/edit/${user.id}">修改用户</a>----<a href="javascript:;" class="del" ref="${user.id }">删除用户</a></li>
  25. </c:forEach>
  26. </ul>
  27. <img alt="" src="/static/img/1.jpg">
  28. <script type="text/javascript" src="http://cdn.staticfile.org/jquery/1.9.1/jquery.min.js"></script>
  29. <script>
  30. $(".del").click(function(){
  31. id=$(this).attr("ref");
  32. type:"delete",
  33. });
  34. });
  35. </script>
  36. </body>
  37. </html>

403.jsp:

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
  3. >
  4. <html>
  5. <head>
  6. <title>权限错误</title>
  7. </head>
  8. <body>
  9. <h1>对不起,您没有权限请求此连接!</h1>
  10. <img alt="" src="/static/img/1.jpg">
  11. </body>
  12. </html>

----------------------------------------------------------------------------------------------------------------

OK,到这里shiro就结束了!现在我们来看Spring Security的。

源:http://hotstrong.iteye.com/blog/1160153

----------------------------------------------------------------------------------------------------------------

使用Spring Security实现权限管理

1、技术目标

  • 了解并创建Security框架所需数据表
  • 为项目添加Spring Security框架
  • 掌握Security框架配置
  • 应用Security框架为项目的CRUD操作绑定权限

注意:本文所用项目为"影片管理",参看

http://hotstrong.iteye.com/blog/1156785

2、权限管理需求描述

  • 为系统中的每个操作定义权限,如定义4个权限:
     1)超级权限,可以使用所有操作
     2)添加影片权限
     3)修改影片权限
     4)删除影片权限
  • 为系统设置管理员帐号、密码
  • 为系统创建权限组,每个权限组可以配置多个操作权限,如创建2个权限组:
     1)"Administrator"权限组,具有超级权限
     2)"影片维护"权限组,具有添加影片、修改影片权限
  • 可将管理员加入权限组,管理员登录后具备权限组所对应操作权限
  • 管理员可不属于某权限组,可为管理员直接分配权限

3、使用准备

3.1)在数据库中创建6张表

t_admin        管理员帐号表

t_role权限表

t_group        权限组表

t_group_role权限组对应权限表

t_group_user管理员所属权限组表

t_user_role管理员对应权限表

建表SQL语句如下:

  1. SET FOREIGN_KEY_CHECKS=0;
  2. ------------------------------
  3. -- 创建管理员帐号表t_admin
  4. -- ----------------------------
  5. CREATE TABLE `t_admin` (
  6. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  7. varchar(12) NOT NULL DEFAULT '' COMMENT '用户密码',
  8. varchar(20) NOT NULL DEFAULT '' COMMENT '用户名字',
  9. varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',
  10. PRIMARY KEY (`id`)
  11. DEFAULT CHARSET=utf8;
  12. -- ----------------------------
  13. -- 添加3个管理帐号
  14. -- ----------------------------
  15. INSERT INTO `t_admin` VALUES ('1', 'admin', 'admin', '');
  16. INSERT INTO `t_admin` VALUES ('4', '123456', 'test', '');
  17. INSERT INTO `t_admin` VALUES ('5', '111111', '111111', '');
  18. -- ----------------------------
  19. -- 创建权限表t_role
  20. -- ----------------------------
  21. CREATE TABLE `t_role` (
  22. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  23. varchar(40) NOT NULL DEFAULT '',
  24. varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',
  25. varchar(40) NOT NULL DEFAULT '' COMMENT '分类',
  26. PRIMARY KEY (`id`)
  27. DEFAULT CHARSET=utf8;
  28. -- ----------------------------
  29. -- 加入4个操作权限
  30. -- ----------------------------
  31. INSERT INTO `t_role` VALUES ('1', 'ROLE_ADMIN', '系统管理员', '系统管理员');
  32. INSERT INTO `t_role` VALUES ('2', 'ROLE_UPDATE_FILM', '修改', '影片管理');
  33. INSERT INTO `t_role` VALUES ('3', 'ROLE_DELETE_FILM', '删除', '影片管理');
  34. INSERT INTO `t_role` VALUES ('4', 'ROLE_ADD_FILM', '添加', '影片管理');
  35. -- ----------------------------
  36. -- 创建权限组表
  37. -- ----------------------------
  38. CREATE TABLE `t_group` (
  39. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  40. varchar(50) NOT NULL DEFAULT '',
  41. PRIMARY KEY (`id`)
  42. DEFAULT CHARSET=utf8;
  43. -- ----------------------------
  44. -- 添加2个权限组
  45. -- ----------------------------
  46. INSERT INTO `t_group` VALUES ('1', 'Administrator');
  47. INSERT INTO `t_group` VALUES ('2', '影片维护');
  48. -- ----------------------------
  49. -- 创建权限组对应权限表t_group_role
  50. -- ----------------------------
  51. CREATE TABLE `t_group_role` (
  52. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  53. bigint(20) unsigned NOT NULL,
  54. bigint(20) unsigned NOT NULL,
  55. PRIMARY KEY (`id`),
  56. UNIQUE KEY `groupid2` (`groupid`,`roleid`),
  57. KEY `roleid` (`roleid`),
  58. CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
  59. CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
  60. DEFAULT CHARSET=utf8;
  61. -- ----------------------------
  62. -- 加入权限组与权限的对应关系
  63. -- ----------------------------
  64. INSERT INTO `t_group_role` VALUES ('1', '1', '1');
  65. INSERT INTO `t_group_role` VALUES ('2', '2', '2');
  66. INSERT INTO `t_group_role` VALUES ('4', '2', '4');
  67. -- ----------------------------
  68. -- 创建管理员所属权限组表t_group_user
  69. -- ----------------------------
  70. CREATE TABLE `t_group_user` (
  71. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  72. bigint(20) unsigned NOT NULL,
  73. bigint(20) unsigned NOT NULL,
  74. PRIMARY KEY (`id`),
  75. KEY `userid` (`userid`),
  76. KEY `groupid` (`groupid`),
  77. CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
  78. CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)
  79. DEFAULT CHARSET=utf8;
  80. -- ----------------------------
  81. -- 将管理员加入权限组
  82. -- ----------------------------
  83. INSERT INTO `t_group_user` VALUES ('1', '1', '1');
  84. INSERT INTO `t_group_user` VALUES ('2', '4', '2');
  85. -- ----------------------------
  86. -- 创建管理员对应权限表t_user_role
  87. -- 设置该表可跳过权限组,为管理员直接分配权限
  88. -- ----------------------------
  89. CREATE TABLE `t_user_role` (
  90. bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  91. bigint(20) unsigned NOT NULL,
  92. bigint(20) unsigned NOT NULL,
  93. PRIMARY KEY (`id`),
  94. KEY `userid` (`userid`),
  95. KEY `roleid` (`roleid`),
  96. CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),
  97. CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
  98. DEFAULT CHARSET=utf8;

3.2)在项目中新增如下jar包(security框架所需jar包):

 注意:以下jar包本文已提供下载

spring-security-config-3.1.0.RC2.jar

spring-security-core-3.1.0.RC2.jar

spring-security-taglibs-3.1.0.RC2.jar

spring-security-web-3.1.0.RC2.jar

3.3)创建如下包,放置登录验证过滤器代码:

com.xxx.security

3.4)在src下创建Spring配置文件applicationContext-security.xml,内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans:beans xmlns="http://www.springframework.org/schema/security"
  3. xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. >
  7. <!-- 这里进行配置 -->
  8. </beans:beans>

3.5)在web.xml中加入security配置,如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. >
  7. <welcome-file-list>
  8. <welcome-file>index.jsp</welcome-file>
  9. </welcome-file-list>
  10. <context-param>
  11. <param-name>contextConfigLocation</param-name>
  12. <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
  13. </context-param>
  14. <!-- 配置Spring Security -->
  15. <filter>
  16. <filter-name>springSecurityFilterChain</filter-name>
  17. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  18. </filter>
  19. <filter-mapping>
  20. <filter-name>springSecurityFilterChain</filter-name>
  21. <url-pattern>/*</url-pattern>
  22. </filter-mapping>
  23. <filter>
  24. <filter-name>struts2</filter-name>
  25. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  26. </filter>
  27. <filter-mapping>
  28. <filter-name>struts2</filter-name>
  29. <url-pattern>/*</url-pattern>
  30. </filter-mapping>
  31. <listener>
  32. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  33. </listener>
  34. </web-app>

4、站点根路径下创建登录页面login.jsp,代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib prefix="s" uri="/struts-tags"%>
  4. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  5. <%
  6. path = request.getContextPath();
  7. basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
  8. >
  9. >
  10. <html xmlns="http://www.w3.org/1999/xhtml">
  11. <head>
  12. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  13. <title>后台登录</title>
  14. </head>
  15. <body onload="document.loginForm.j_username.focus();">
  16. <!-- 登录表单 -->
  17. <form name="loginForm" action="<c:url value='/j_spring_security_check'/>" method="post">
  18. <!-- 登录失败后,显示之前的登录名 -->
  19. <input type='text' name='j_username' class="txtinput"
  20. value='<c:if test="${not empty param.login_error}" >
  21. <c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' />
  22. <br />
  23. <input type='password' name='j_password' class="txtinput" />
  24. <br />
  25. <input type="checkbox" name="_spring_security_remember_me" />
  26. <input name="submit" type="submit" value="提交" />
  27. <input name="reset" type="reset" value="重置" />
  28. </form>
  29. <br />
  30. <!-- 显示登录失败原因 -->
  31. <c:if test="${not empty param.error}">
  32. <font color="red"> 登录失败<br />
  33. <br />
  34. <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />. </font>
  35. </c:if>
  36. </body>
  37. </html>

5、站点根路径下创建注销页面loggedout.jsp,代码如下:

  1. <%@page session="false" %>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%@ page pageEncoding="UTF-8"%>
  4. <%
  5. path = request.getContextPath();
  6. basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
  7. >
  8. >
  9. <html xmlns="http://www.w3.org/1999/xhtml">
  10. <head>
  11. <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  12. <title>登出</title>
  13. </head>
  14. <body>
  15. <a href="<c:url value='/login.jsp'/>">点击这里登录</a>
  16. </body>
  17. </html>

6、站点根路径下创建HttpSession超时提示页面timeout.jsp,代码如下:

  1. <%@page session="false" %>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
  4. <%
  5. path = request.getContextPath();
  6. basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
  7. >
  8. >
  9. <html xmlns="http://www.w3.org/1999/xhtml">
  10. <head>
  11. <title>用户失效</title>
  12. </head>
  13. <body>
  14. <br />
  15. <a href="<c:url value='/login.jsp'/>" >
  16. </a>
  17. </body>
  18. </html>

7、在com.xxx.security包下创建登录验证过滤器,该过滤器可用于在管理员登录时进行日志记录等相关操作,包括两个类:

  • LoginUsernamePasswordAuthenticationFilter
  • LoginSuccessHandler

7.1)LoginUsernamePasswordAuthenticationFilter代码如下:

  1. package com.xxx.security;
  2. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  3. public class LoginUsernamePasswordAuthenticationFilter extends
  4. }

7.2)LoginSuccessHandler代码如下:

  1. package com.xxx.security;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import org.springframework.security.core.Authentication;
  7. import org.springframework.security.core.userdetails.UserDetails;
  8. import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
  9. /**
  10. * 处理管理员登录日志
  11. *
  12. */
  13. public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
  14. @Override
  15. public void onAuthenticationSuccess(HttpServletRequest request,
  16. throws IOException,
  17. //输出登录提示信息
  18. "管理员 " + userDetails.getUsername() + " 登录");
  19. super.onAuthenticationSuccess(request, response, authentication);
  20. }

8、在applicationContext-security.xml中加入权限管理配置,如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans:beans xmlns="http://www.springframework.org/schema/security"
  3. xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. >
  7. <http >
  8. <!-- 不拦截login.jsp -->
  9. <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
  10. <!--仅拦截到manager下面的内容,具备access对应权限的-->
  11. <intercept-url pattern="/manager/**" access="ROLE_ADMIN,ROLE_UPDATE_FILM,ROLE_DELETE_FILM,ROLE_ADD_FILM" />
  12. <!-- 设置登录过滤器 -->
  13. <custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />
  14. <!-- 登录表单设置 -->
  15. <form-login login-page="/login.jsp"
  16. default-target-url="/manager/films.jsp"
  17. authentication-failure-url="/login.jsp?error=true" />
  18. <!-- 登出操作后跳转到该页面 -->
  19. <logout logout-success-url="/loggedout.jsp"
  20. delete-cookies="JSESSIONID" />
  21. <remember-me />
  22. <!-- SESSION超时后跳转到该页面 -->
  23. <session-management invalid-session-url="/timeout.jsp">
  24. </session-management>
  25. </http>
  26. <authentication-manager alias="authenticationManager">
  27. <authentication-provider>
  28. 直接使用SQL语句查询登录帐号对应权限,
  29. authorities-by-username-query:查询登录用户权限(登录用户可以不属于任何组,从t_user_role表中获取权限)
  30. -->
  31. <jdbc-user-service data-source-ref="dataSource"
  32. group-authorities-by-username-query="SELECT g.id,g.groupname,role.role
  33. LEFT OUTER JOIN t_group_role AS grouprole ON (g.id = grouprole.groupid)
  34. role.id = grouprole.roleid)
  35. g.id = groupuser.groupid)
  36. t_admin.id = groupuser.userid)
  37. t_admin.nickname = ?"
  38. users-by-username-query="SELECT t_admin.nickname AS username,t_admin.passwd as password,'true' AS enabled
  39. WHERE t_admin.nickname = ?"
  40. authorities-by-username-query="SELECT t_admin.nickname AS username,role.role as authorities
  41. LEFT OUTER JOIN t_user_role AS userrole ON(t_admin.id = userrole.userid)
  42. userrole.roleid = role.id)
  43. t_admin.nickname = ?" />
  44. </authentication-provider>
  45. </authentication-manager>
  46. <!-- 自定义消息 -->
  47. <b:bean id="messageSource"
  48. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  49. <b:property name="basename"
  50. value="classpath:org/springframework/security/messages" />
  51. </b:bean>
  52. <!-- 定制登录过滤器 -->
  53. <beans:bean id="loginSuccessHandler" class="com.xxx.security.LoginSuccessHandler">
  54. <b:property name="defaultTargetUrl">
  55. <!-- 登录成功后转发到该页面 -->
  56. <b:value>/manager/films.jsp</b:value>
  57. </b:property>
  58. </beans:bean>
  59. <beans:bean id="authenticationProcessingFilter" class="com.xxx.security.LoginUsernamePasswordAuthenticationFilter">
  60. <beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"></beans:property>
  61. <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"></beans:property>
  62. <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
  63. </beans:bean>
  64. <beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
  65. <beans:property name="defaultFailureUrl">
  66. <!-- 登录失败后转发到该页面 -->
  67. <beans:value>/login.jsp?error=true</beans:value>
  68. </beans:property>
  69. </beans:bean>
  70. </beans:beans>

注:

Spring Security 默认action="j_spring_security_check",让很多人不理解这个请求之后会跳转到哪里去,
这里我们就看
配置文件里这个<http></http>标签,这个标签里面最基本的是intercept-url,用来设置访问权限的。
<http></http>标签里面有个form-login 标签,这个标签有很多属性,大概情况如下:
form-login属性详解
1. login-page 自定义登录页url,默认为/login
2. login-processing-url 登录请求拦截的url,也就是form表单提交时指定的action
3. default-target-url 默认登录成功后跳转的url
4. always-use-default-target 是否总是使用默认的登录成功后跳转url
5. authentication-failure-url 登录失败后跳转的url
6. username-parameter 用户名的请求字段 默认为userName
7. password-parameter 密码的请求字段 默认为password
8. authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
9. authentication-success-forward-url 用于authentication-failure-handler-ref
10. authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
11. authentication-failure-forward-url 用于authentication-failure-handler-ref
12. authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用

9、为影片页面films.jsp定制操作权限,定制后,不同的帐号登录会看到不同的操作,

比如,帐号"admin"属于权限组"Administrator",具备权限"ROLE_ADMIN",登录后

可以看到所有操作,帐号"test"属于权限组"影片维护",具备权限"ROLE_UPDATE_FILM"

和"ROLE_ADD_FILM",登录后只能看到"添加影片信息"和"修改"操作

films.jsp页面权限分布图:

films.jsp代码如下:

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. >
  3. <%@taglib uri="/struts-tags" prefix="s" %>
  4. <%@ taglib prefix="security"
  5. uri="http://www.springframework.org/security/tags"%>
  6. <%
  7. path = request.getContextPath();
  8. basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  9. >
  10. >
  11. <html>
  12. <head>
  13. <title>信息操作</title>
  14. </head>
  15. <body>
  16. <s:form action="/film/findFilm" method="post">
  17. <s:submit value=" 获取所有影片信息 "></s:submit>
  18. </s:form>
  19. <!-- 添加影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_ADD_FILM权限可以执行 -->
  20. <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_ADD_FILM">
  21. <a href="<%=basePath %>manager/insertFilm.jsp">添加影片信息</a><br />
  22. </security:authorize>
  23. <s:if test="filmList != null">
  24. <table border="1" width="40%">
  25. <tr>
  26. <th>序号</th><th>影片名</th><th>操作</th>
  27. </tr>
  28. <%-- 遍历影片信息 --%>
  29. <s:iterator var="film" value="filmList" status="st">
  30. <tr>
  31. <td><s:property value="#st.index+1" /></td>
  32. <td><s:property value="fname" /></td>
  33. <td>
  34. <!-- 修改影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_UPDATE_FILM权限可以执行 -->
  35. <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_UPDATE_FILM">
  36. <s:url id="detailUrl" value="/film/detailFilm">
  37. <s:param name="id" value="%{id}"/>
  38. </s:url>
  39. <s:a href="%{detailUrl}">[修改]</s:a>&nbsp;
  40. </security:authorize>
  41. <!-- 删除影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_DELETE_FILM权限可以执行 -->
  42. <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_DELETE_FILM">
  43. <s:url id="deleteUrl" value="/film/deleteFilm">
  44. <s:param name="id" value="%{id}"/>
  45. </s:url>
  46. <s:a href="%{deleteUrl}">[删除]</s:a>
  47. </security:authorize>
  48. </td>
  49. </tr>
  50. </s:iterator>
  51. </table>
  52. </s:if>
  53. </body>
  54. </html>

Shrio在线教程:
http://www.sojson.com/jc/shiro.html
Shiro + Redis 源码

http://www.sojson.com/shiro

Spring Security和Shiro的比较和使用的更多相关文章

  1. Spring security与shiro

    shiro更轻量级,spring security过于复杂. Apache Shiro 使用手册(一)Shiro架构介绍 Spring Security笔记:Remember Me(下次自动登录)

  2. 权限控制框架Spring Security 和Shiro 的总结

    关于权限控制,一开始感觉比较难,后来先是接触了Spring Security 学起来也比较吃力,再是学习了Shiro,感觉简单很多. 总体来说这些框架,主要做了两个事情 Authentication: ...

  3. 安全框架Shiro和Spring Security比较

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势. Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证. ...

  4. 权限框架Apache Shiro 和 Spring Security

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授 ...

  5. web应用安全框架选型:Spring Security与Apache Shiro

    一. SpringSecurity 框架简介 官网:https://projects.spring.io/spring-security/ 源代码: https://github.com/spring ...

  6. 【权限管理】Apache Shiro和Spring Security的对比

    一.Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Secu ...

  7. Spring Boot:整合Spring Security

    综合概述 Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication)和授权(Author ...

  8. Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  9. spring security学习总结

    这几天一直在学习spring security的相关知识.逛各大论坛,看相关api与教学视频,获益良多! 简介 Spring Security是为基于Spring的企业应用系统提供声明式的安全访问控制 ...

随机推荐

  1. 本机和虚拟机互联 设置静态IP vmware 虚拟网络 桥接 NAT 仅主机 自定义

  2. mysql导入文件

    手里有一个web源码工程文件夹 mysql导入文件: 新建连接,名称随意,用修改设置的用户密码登录,我的连接名称是eee 右击information_schema,建立数据库,数据库名称源码文件名,字 ...

  3. Linux 下 FTP虚拟用户的使用配置

    Linux下FTP虚拟用户的使用配置 Linux的FTP服务支持3种用户: 1.匿名帐户 2.本地帐户 3.虚拟用户 为什么要使用虚拟用户: 匿名帐户可以很好的保证FTP服务器的安全性,但是,对匿名用 ...

  4. 牛客网Java刷题知识点之抽象类与接口

    不多说,直接上干货! 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于它们的存在才赋予java强大的面向对象的能力. ...

  5. eclipse下 Failed to find an AVD compatible with target 的解决方法

    第一个Android测试环境下的程序出现这个问题: [2012-04-24 13:18:29 - xxxx] ------------------------------ [2012-04-24 13 ...

  6. 开源分布式Job系统,调度与业务分离-HttpJob.Agent组件介绍以及如何使用

    项目介绍: Hangfire:是一个开源的job调度系统,支持分布式JOB!! Hangfire.HttpJob 是我针对Hangfire开发的一个组件,该组件和Hangfire本身是独立的.可以独立 ...

  7. untiy3d开发环境搭建和开发准备

    1.到untiy3d官网上下载untiy3d的软件(这里我使用的是个人版的5.3.61f做学习使用) 2.安装vs2012 3.因为unity3d和vs的版本有一定的版本对应关系,我这里使用vs201 ...

  8. 装饰者模式及php实现

    装饰模式(Decorator Pattern) : 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活.其别名也可以称为包装器(Wr ...

  9. 【selenium学习笔记一】python + selenium定位页面元素的办法。

    1.什么是Selenium,为什么web测试,大家都用它? Selenium设计初衷就是为web项目的验收测试再开发.内核使用的是javaScript语言编写,几乎支持所以能运行javaScript的 ...

  10. POJ 2288 Islands and Bridges (状压DP,变形)

    题意: 给一个无向图,n个点m条边,每个点有点权,要求找到一条哈密顿路径,使得该路径的f(path)值最大.输出f值,若有多条最大f值的路径,输出路径数量. f值由如下3点累加而来: (1)所有点权之 ...