Spring安全方法安全注释(Spring Security Method Security Annotations)
最近,我开始了一些个人项目,我决定实施Spring Security。 我以前曾试图这样做,但那时我没有比现在更好的运气。 我解决了这个问题,但是那个方法(直接从代码访问安全上下文并检查它为当前用户包含的角色字符串)感觉就像一个黑客,我想这次正确。
现在我有Spring Security MOSTLY功能,据我所知...我可以尝试使用基于角色的重定向转到页面,它会将我重定向到登录页面。 我可以使用好的或坏的信息登录并发送到正确的位置。 我不能做的,我从未设法做的,是让@Secured或@PreAuthorize注释按照我希望的方式运行。
让我试着解释(代码将遵循)。 我的欢迎/登录页面是index.jsp,当您登录时,Spring Security会将您发送到login.html,这是我在LoginController类中映射的方法。 在该方法中,我尝试调用一大堆其他方法:这些都不应该是最终的,我只是试图向自己证明事情正在运行。
我调用了两个由@Secured保护的方法,以及两个由@PreAuthorize保护的方法,一个是“ROLE_ADMIN”,另一个是“ROLE_USER”。 我登录的帐户只具有ROLE_USER权限。 在这种情况下,我希望将其重定向到我的accessdenied.jsp页面,因为已将其设置为我的Spring Security的access-denied-page属性的目标。 我没想到的,也就是我所看到的,是每个方法都成功调用并在我登录时运行。
我(至少试图)按照教程进行操作。 我在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>
感谢您提供的任何帮助。
Recently, I have begun a bit of a personal project, and I decided to implement Spring Security. I have attempted to do so before, but I had no better luck that time than I am now. I got around the problem then, but that method (accessing the security context directly from the code and checking the string of roles it contains for the current user) feels like a hack, and I would like to get it right this time.
Right now I have Spring Security MOSTLY functioning, as far as I know...I can attempt to go to a page with a role-based redirect, and it will redirect me to the login page. I can log in with good or bad information and be sent to the proper location. What I cannot do, what I have never managed to do, is get the @Secured or @PreAuthorize annotation to function as I would hope.
Let me try to explain (code will follow). My welcome/login page is index.jsp and, when you log in, Spring Security sends you to login.html which is where I have a method in my LoginController class mapped. Inside that method, I try to call a large set of other methods: none of this is supposed to be final, I am just trying to get prove to myself that things are running.
I call two methods that are secured by @Secured, and two methods that are secured by @PreAuthorize, one "ROLE_ADMIN" and one "ROLE_USER" each. The account that I am logging into only has the ROLE_USER authority. This being the case, I would expect to get redirected to my accessdenied.jsp page as per having set that as the target of my Spring Security's access-denied-page attribute. What I do not expect, and what I am seeing, is that every method is successfully called and run when I log in.
I have (at least attempted to) follow the tutorials. I have spent days on Google, reading everything that I can find. I have merged my security context into my context, and everything else that came to my attention as a potential solution. I apologize if I have been a mite long-winded, but I would rather provide too much information than too little. To that end, the following is my code:
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>
Thank you for any help that you can provide.
原文:https://stackoverflow.com/questions/12082904
最满意答案
您可以在窗口调整大小时显示它并隐藏它,这样您就可以确保菜单始终在大屏幕中可见,而在小屏幕中则不可见。
$( window ).resize(function() { if($( window ).width() >= 690) { $("#responsive").show(); } else { $("#responsive").hide(); } });
You could show it and hide it on window resize, so that you make sure the menu is always visible in big screens and not visible in small screens.
$( window ).resize(function() { if($( window ).width() >= 690) { $("#responsive").show(); } else { $("#responsive").hide(); } });
相关问答
更多-
我找到了答案! 我删除位置:相对来自css .over_meno li a {},现在每件事情都是正确的 i found the answer! i delete position:relative from css .over_meno li a{}, every things correct now
-
.toggleClass() $('p').toggleClass('displayNone displayBlock');////Adds 'displayNone', removes 'displayBlock' and vice versa 您需要将类添加到p元素:
DEMO 如果你想要动画 :一起使用opicity和transition ,因为display:none不适用于transition 。 这是演示: 过渡演示 更新 使用幻灯片toog ...
-
最后,我得到了答案..我在标题附近添加了一个多余的标签,这就是为什么它不显示,删除后,现在我的档案工作得非常好。
jQuery slideToggle()(jQuery slideToggle())[2022-09-12]
这是一个HTML结构问题。 在对应的#box1, #box2 and #box3获取你的div.panels ,它应该没问题。 而且,你不必放一个float: left; 使用此方法在div.panels上的属性。 It is a HTML structure problem. Get your div.panels in the correspondant #box1, #box2 and #box3 and it should be fine. And also, you will not have t ...您可以在窗口调整大小时显示它并隐藏它,这样您就可以确保菜单始终在大屏幕中可见,而在小屏幕中则不可见。 $( window ).resize(function() { if($( window ).width() >= 690) { $("#responsive").show(); } else { $("#responsive").hide(); } }); You could show it and hide it on window res ...这是因为你最初并没有使用.slideToggle()隐藏,而是设置:隐藏在CSS中,这导致.slideToggle()回退到CSS标准(display:block)。 如果你将元素称为display:inline,然后是.slideToggle()它在初始加载时隐藏,.slideToggle()存储内联状态 That is because you're not initially hiding with .slideToggle(), but rather setting :hidden in the CS ...如果我理解正确,在页面加载时你只想显示“切换”。 单击“切换”时,您要显示其他三个部分。 为此,您需要将其他三个部分放在包装器div中,然后在包装器div上使用幻灯片切换。 快速jsfiddle: http : //jsfiddle.net/43byX/ 以下是您的代码的修改版本: