最近,我开始了一些个人项目,并决定实施Spring Security。我以前曾试图这样做,但那次比我现在没有更好的运气。然后,我解决了这个问题,但是这种方法(直接从代码访问安全上下文并检查它包含的当前用户的角色字符串)感觉就像是一个黑客,我想这次是正确的。Spring安全方法安全注释
现在我有Spring Security大部分功能,据我所知...我可以尝试转到基于角色的重定向页面,它会将我重定向到登录页面。我可以登录信息好的或不正确的信息并发送到正确的位置。我做不到的,我从来没有设法做到的,就是让@Secured或@PreAuthorize注解起作用,就像我希望的那样。
让我试着解释(代码将随后)。我的欢迎/登录页面是index.jsp,当您登录时,Spring Security会将您发送到login.html,这是我在LoginController类中映射了一个方法的地方。在这个方法里面,我尝试调用一大组其他方法:这些都不是最终的,我只是试图向自己证明事情正在运行。
我调用了两个由@Secured保护的方法,以及两个分别由@PreAuthorize,一个“ROLE_ADMIN”和一个“ROLE_USER”保护的方法。我登录的帐户只有ROLE_USER权限。在这种情况下,我希望将其重定向到我的accessdenied.jsp页面,并将其设置为我的Spring Security的访问被拒绝页面属性的目标。我不期望的以及我所看到的是,每种方法都在我登录时成功调用并运行。
我有(至少试过)按照教程。我花了几天时间在Google上阅读我能找到的所有内容。我已将我的安全上下文合并到我的上下文中,以及其他一切引起我注意的潜在解决方案。我很抱歉,如果我是一个长期螨,但我宁愿提供太多的信息,而不是太少。为此,下面是我的代码:
的index.jsp
<html>
<body>
<form action="j_spring_security_check" method="POST">
<label for="j_username">Name:</label>
<input id="j_username" type='text' name='j_username' />
<br />
<label for="j_password" class="passwordField">Password:</label>
<input id="j_password" type='password' name='j_password' />
<br />
<input id="proceed" type="submit" value="Submit" />
</form>
</body>
</html>
LoginController.java
package cribbage.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.jdbc.core.JdbcTemplate;
import cribbage.database.entity.Test;
@Controller
public class LoginController {
@Autowired
JdbcTemplate t;
@RequestMapping(value = "/login")
public ModelAndView login(HttpServletRequest request) {
test();
test2();
test3();
test4();
return new ModelAndView("test.jsp");
}
@Secured("ROLE_ADMIN")
public void test(){
System.out.println("Test One");
}
@Secured("ROLE_USER")
public void test2(){
System.out.println("Test Two");
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void test3(){
System.out.println("Test Three");
}
@PreAuthorize("hasRole('ROLE_USER')")
public void test4(){
System.out.println("Test Four");
}
}
的web.xml
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<display-name>Spring Security Tutorial Application</display-name>
<!-- - Location of the XML file that defines the root application context
- Applied by ContextLoaderListener. -->
<context-param>
<description>Spring context file</description>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<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>
<!-- - Provides core MVC application controller. See bank-servlet.xml. -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
的applicationContext。 xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:property-placeholder location="classpath:*.properties" />
<mvc:annotation-driven />
<!-- Which packages to scan when looking for beans defined with @Component -->
<context:component-scan scoped-proxy="targetClass"
base-package="cribbage.controller
cribbage.database.dao
cribbage.database.entity" />
<context:annotation-config />
<!-- Turn on AspectJ @Configurable support -->
<!-- Turn on @Autowired, @PostConstruct etc support -->
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<!-- Add Transaction support -->
<!-- Use @Transaction annotations for managing transactions -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource" />
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"
p:defaultLocale="en_US" />
<!-- For database, uses maven filtering to fill in place holders -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="1" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<security:global-method-security
secured-annotations="enabled" pre-post-annotations="enabled" />
的applicationContext-security.xml文件
<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.1.xsd">
<http pattern="/CSS/**" security="none" />
<http auto-config="true" use-expressions="true" access-denied-page="/accessdenied.jsp">
<form-login always-use-default-target="false"
login-processing-url="/j_spring_security_check" default-target-url="/login.html"
login-page="/index.jsp" authentication-failure-url="/loginFailed.jsp" />
<logout logout-url="/j_spring_security_logout" />
<intercept-url pattern="/test.jsp" access="hasRole('ROLE_USER')" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,user_password,enabled from users where username=?"
authorities-by-username-query="select username,authority,enabled from users where username=?" />
</authentication-provider>
</authentication-manager>
感谢您的帮助,您可以提供。
我想直接访问test()方法,它的工作原理。你这样做的方式,它不起作用(即使我有相同的情况)。我怀疑它是否意味着那样。我不确定。所以我已经发布了一个[问题](http://stackoverflow.com/questions/12084480/spring-security-method-level-security-doesnt-work-on-calling-from-another-meth)。 – shazinltc
而我没有看到真正的时间场景,你会真正做到这一点,如果你有一个让我知道。 – shazinltc
这并不是说我有相信会发生这种情况,我只是很难理解为什么安全性会绕过这一点。基本上,我只是试图证明自己的注释是有效的,但我这样做显然是不可能的方式!正如你所说,这显然不是它的工作原理。 –