Spring Security初体验

1,配置过滤器

为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了。

<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>

2,使用命名空间

ApplicationContext.XML中配置或者另外单独使用一个Security.XML都可以,我们这里使用单独的xml来对Security进行配置.

<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-3.0.xsd
             
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
</beans>

我们通常使用"security"作为默认的命名空间,而不是"beans",这意味着我们可以省略所有security命名空间元素的前缀,使上下文更容易阅读

<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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
             
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
</beans:beans>

3,配置认证提供接口和用户信息(这里使用内存用户)

<global-method-security pre-post-annotations="enabled">

</global-method-security>

<http use-expressions="true" access-denied-page="/AccessDenied.jsp">

<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

<form-login />

</http>

<authentication-manager>

<authentication-provider>

<user-service>

<user name="rod" password="rod"

authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />

</user-service>

</authentication-provider>

</authentication-manager>

<beans:bean id="loggerListener"

class="org.springframework.security.authentication.event.LoggerListener" />

这里配置pre-post-annotations="enabled"可以在接口函数(必须在接口中声明)/页面使用标签/表达式进行权限判断

  • 如下表达式要求用户必须具备ROLE_SUPERVISOR角色才能调用

import org.springframework.security.access.prepost.PreAuthorize;

import sshDemo.Entities.*;

public interface IOwnerService {

@PreAuthorize("hasRole('ROLE_SUPERVISOR')")

public List<Owners> getOwners();

}

表达式基于

org.springframework.security.access.expression.SecurityExpressionRoot类提供权限判断.

  • 另外也可以在页面中使用授权标签如下的sec:authorize要求具备ROLE_SUPERVISOR或者ROLE_TELLER才能使用该链接.

<%@ taglib prefix="s" uri="/struts-tags"%>

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<sec:authorize access="hasAnyRole('ROLE_SUPERVISOR','ROLE_TELLER')">

<a href="<s:url action='listAction'/>">List</a>

</sec:authorize>

security:authorize 标签声明下面的属性:

  • ifAllGranted:这个标签列出的所有角色必须授权,才能输出标签的内容。
  • ifAnyGranted:任何一个这个标签列出的角色必须授权,才能输出标签的内容。
  • ifNotGranted:这个标签列出的角色没有一个是授权的,才能输出标签的内容。

3,使用自定义登陆页面

创建login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt"%>

<html>

  <head>

    <base href="<%=basePath%>">

   

    <title>Login</title>

   

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">   

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

  </head>

 

  <body>

 

  <c:if test="${param.error}">

    <font color="red"> Your login attempt was not successful, try

    again.<br />

    <br />

    Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>.

    </font>

</c:if>

<form action="${pageContext.request.contextPath}/j_spring_security_check" style="260px;text-align:center;" method="post">

  <fieldset>

    <legend>登陆</legend>

    用户: <input type="text" name="j_username" style="150px;" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}"/><br />

    密码: <input type="password" name="j_password" style="150px;" /><br />

    <input type="checkbox" name="_spring_security_remember_me" />两周之内不必登陆<br />

    <input type="submit" value="登陆"/>

    <input type="reset" value="重置"/>

  </fieldset>

</form>

  </body>

</html>

 

配置登陆界面

<http>

...

<form-login login-page="/login.jsp"

authentication-failure-url="/login.jsp?error=true"

default-target-url="/" />

...

</http>

4,配置退出操作

在页面中添加退出操作

<a href="j_spring_security_logout">Logout</a>

配置退出操作

<http>

...

<logout logout-success-url="/login.jsp" />

...

</http>

5,配置访问拒绝操作

创建访问拒绝页面

<%@ page contentType="text/html; charset=GBK" %>

<html> 

<head></head> 

<body > 

    <div id="header"></div>     

    <div id="content" style=" 60%">

                      <strong>Access Denied</strong>

    </div>              

</body>

</html>

配置访问拒绝重定向页面

<http access-denied-page="/AccessDenied.jsp">

...

</http>

6,运行调试

注意事项:

1,如果跟Struts2结合使用需要将spring security的配置放在struts2前面防止struts2将相应的处理截取出现如下错误:

Q:为何登录时出现There is no Action mapped for namespace / and action name j_spring_security_check.

 A:这是因为登陆所发送的请求先被struts2的过滤器拦截了,为了试登陆请求可以被Spring Security正常处理,需要在web.xml中将Spring Security的过滤器放在struts2之前。

2Struts结合Spring Security使用时出现Access Denied但是没有跳到对应的AccessDenied.jsp页面.

Q:Access Denied但是没有跳到对应的AccessDenied.jsp页面.

 

A:解决方法还没有

原文地址:https://www.cnblogs.com/SkyMouse/p/2340744.html