我是春天安全的新手。
我尝试在我的应用程序中使用spring security。基本的Spring安全功能正常。
但是当我尝试保护方法只允许特定角色时,它不受保护,并且该方法可以适用于每个角色。
这里我给出了我的代码片段。我可能知道我错了。
我用于此应用程序的库是
01.aopalliance-1.0.jar
02.jcl-over-slf4j-1.6.1.jar
03.jstl-1.2.jar
04.logback-classic-0.9.29.jar
05.logback-core-0.9.29.jar
06.mysql-connector-java-5.1.12-bin.jar
07.org.springframework.jdbc-3.1.0.RC1.jar
08.org.springframework.transaction-3.1.0.RC1.jar
09.slf4j-api-1.6.1.jar
10.spring-aop-3.0.6.RELEASE.jar
11.spring-asm-3.0.6.RELEASE.jar
12.spring-beans-3.0.6.RELEASE.jar
13.spring-context-3.0.6.RELEASE.jar
14.spring-context-support-3.0.6.RELEASE.jar
15.spring-core-3.0.6.RELEASE.jar
16.spring-expression-3.0.6.RELEASE.jar
17.spring-security-config-3.1.0.RC3.jar
18.spring-security-core-3.1.0.RC3.jar
19.spring-security-crypto-3.1.0.RC3.jar
20.spring-security-taglibs-3.1.0.RC3.jar
21.spring-security-web-3.1.0.RC3.jar
22.spring-web-3.0.6.RELEASE.jar
23.spring-webmvc-3.0.6.RELEASE.jar
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/security-app-context.xml
/WEB-INF/application-data-source.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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
- Provides core MVC application controller. See bank-servlet.xml.
-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
调度-servlet.xml中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd"
xmlns:ns1="http://www.springframework.org/schema/security">
<ns1:global-method-security pre-post-annotations="enabled"/>
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/pages/result/"
p:suffix=".jsp" >
<property name="viewClass">
<value>
org.springframework.web.servlet.view.JstlView
</value>
</property>
</bean>
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
<bean name="/action.htm" id="action" class="com.spt3.controller.ActionController">
<property name="methodNameResolver">
<ref bean="paramResolver"/>
</property>
</bean>
<bean id="paramResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName">
<value>action</value>
</property>
</bean>
</beans>
的applicationContext.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-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
</beans>
安全应用程式内-context.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">
<global-method-security pre-post-annotations="enabled"/>
<http use-expressions="true" auto-config="true" access-denied-page="/pages/accessDenied.jsp">
<intercept-url pattern="/index.jsp" access="permitAll" />
<intercept-url pattern="/**.htm" access="isAuthenticated()"/>
<intercept-url pattern="/pages/*" access="permitAll" />
<intercept-url pattern="/user/*" access="isAuthenticated()"/>
<intercept-url pattern="/md/*" access="hasRole('MD')"/>
<intercept-url pattern="/admin/*" access="hasAnyRole('Administrator','MD')"/>
<intercept-url pattern="/manager/*" access="hasAnyRole('Manager','MD')"/>
<form-login login-page="/pages/login.jsp" authentication-failure-url="/pages/loginfailed.jsp"/>
<logout logout-success-url="/index.jsp"/>
</http>
<beans:bean id="encoder" class="com.spt3.encoder.MyPasswordEncoder"/>
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder"/>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username,password, enabled
from users where username=?"
authorities-by-username-query="
select u.username, ur.authority from users u, user_roles ur where u.user_id = ur.user_id and u.username =? "
/>
</authentication-provider>
</authentication-manager>
</beans:beans>
应用 - 数据 - source.xml
<beans xmlns="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">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/app" />
<property name="username" value="uname" />
<property name="password" value="pword" />
</bean>
</beans>
ActionController.java
package com.spt3.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.spt3.infc.ActionInterface;
import org.springframework.security.access.prepost.PreAuthorize;
public class ActionController extends MultiActionController implements ActionInterface {
public ActionController(){
}
public ModelAndView getResult(HttpServletRequest request,HttpServletResponse response)throws Exception{
System.out.println(" - - - - - getResult() - - - - - ");
try{
this.getPersonalInformation("MD");
}catch(Exception e){
System.out.println(" Exception : "+e);
}
return new ModelAndView("result");
}
public void getPersonalInformation(String role){
System.out.println(" "+role+"'s-Personal Information.");
}
}
ActionInterface.java
package com.spt3.infc;
import org.springframework.security.access.prepost.PreAuthorize;
public interface ActionInterface {
@PreAuthorize("hasRole('MD')") // Secured method only for role MD
public void getPersonalInformation(String role);
}
从url访问getResult()方法时( 可以调用http://127.0.0.1:8080/myapp/action.htm?action=getResult)安全方法。
我的预期结果应为
现在实际结果是
使用豆子后 - 编辑(1)此处
使用bean注入时发生了同样的问题。
我在这里用代码片段更改了文件。
ActionController.java就像
package com.spt3.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.spt3.infc.ActionInterface;
public class ActionController extends MultiActionController {
private ActionInterface actionInterface;
public ActionController(){
}
public ActionController(ActionInterface actionInterface){
this.actionInterface=actionInterface;
}
public ModelAndView getResult(HttpServletRequest request,HttpServletResponse response)throws Exception{
System.out.println(" - - - - - getResult() - - - - - ");
try{
actionInterface.getPersonalInformation("MD");
}catch(Exception e){
System.out.println(" Exception : "+e);
}
return new ModelAndView("result");
}
}
ActionInterface.java
package com.spt3.infc;
public interface ActionInterface {
public void getPersonalInformation(String role);
}
bean类名为ActionBean.java
package com.spt3.bean;
import com.spt3.infc.ActionInterface;
import org.springframework.security.access.annotation.Secured;
public class ActionBean implements ActionInterface{
@Secured("MD")
public void getPersonalInformation(String role){
System.out.println(" "+role+"'s-Personal Information.");
}
}
我使用构造函数注入来注入对象。
<bean id="actionBean" class="com.spt3.bean.ActionBean"/> <!-- Bean class -->
<bean name="/action.htm" id="action" class="com.spt3.controller.ActionController">
<property name="methodNameResolver">
<ref bean="paramResolver"/>
</property>
<constructor-arg index="0" ref="actionBean"/> <!-- Injecting object to controller -->
</bean>
我错了。请给我解决方案。
问题已解决。
这是我遵循的步骤。
最后,当程序成功运行时,类看起来像以下代码段。
ActionBean是我创建的一个单独的类,我实现了ActionInterface.java类并实现了方法getPersonalInformation()方法。
ActionInterface.java看起来像这样
package com.spt3.infc;
public interface ActionInterface {
public void getPersonalInformation(String role);
}
和ActionBean.java看起来像这样
package com.spt3.bean;
import com.spt3.infc.ActionInterface;
import org.springframework.security.access.prepost.PreAuthorize;
public class ActionBean implements ActionInterface{
@PreAuthorize("hasRole('MD')")
public void getPersonalInformation(String role){
System.out.println(" "+role+"'s-Personal Information.");
}
}
ActionController.java看起来像这样
package com.spt3.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.spt3.infc.ActionInterface;
public class ActionController extends MultiActionController {
private ActionInterface actionInterface;
public ActionController(){
}
public ActionController(ActionInterface actionInterface){
this.actionInterface=actionInterface;
}
public ModelAndView getResult(HttpServletRequest request,HttpServletResponse response)throws Exception{
System.out.println(" - - - - - getResult() - - - - - ");
try{
actionInterface.getPersonalInformation("MD");
}catch(Exception e){
System.out.println(" Exception : "+e);
}
return new ModelAndView("result");
}
}
祝你好运......
非常感谢。
答案 0 :(得分:3)
Spring安全性通过使用spring bean周围的代理来工作,它绕过对bean方法的调用,如果用户没有适当的角色则抛出异常。但是你的控制器不会调用任何spring bean方法。它确实调用了一个实例方法:this.getPersonalInformation()
。
执行此操作时,您不会调用另一个Spring bean方法,因此Spring无法拦截调用,因此无法验证用户是否具有相应的角色。
将getPersonalInformation
方法放在另一个Spring bean中,在控制器中注入这个bean,一切都应该没问题。
旁注:为什么不简单地使用@Secured("MD")
注释来表示这种情况?为什么不直接在getResult方法上添加注释?