Spring MVC-sprawdzanie czy użytkownik jest już zalogowany przez Spring Security?
Mam aplikację Spring MVC.używa własnej strony logowania . Po pomyślnym zalogowaniu obiekt "LOGGED_IN_USER" jest umieszczany w sesji HTTPSession.
Chcę zezwolić tylko uwierzytelnionym użytkownikom na dostęp do adresów URL. Wiem, że mogę to osiągnąć za pomocą filtra internetowego. Ale, ta część chcę zrobić za pomocą Spring Security (moje sprawdzenie pozostanie taka sama-poszukaj 'LOGGED_IN_USER' obiekt w HTTPSession, jeśli obecny jesteś zalogowany).
moim ograniczeniem jest to, że nie mogę zmienić Zachowanie logowania w chwili obecnej - które nie będzie jeszcze korzystać z Spring Security.
Jakiego aspektu Spring Security mogę użyć, aby osiągnąć tę część samodzielnie - sprawdzić, czy żądanie jest uwierzytelnione (od zalogowanego użytkownika)?
3 answers
Istnieją co najmniej 4 różne sposoby:
Spring security XML configuration
To najprostszy sposób
<security:http auto-config="true" use-expressions="true" ...>
...
<security:intercept-url pattern="/forAll/**" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
- @see Spring Security Reference, Chapter 16.1.1 Common Built-in Expressions
- @see Spring Security Reference, Rozdział 16.2 Web Security Expressions
Per @ Zabezpieczona Adnotacja
Wymaga <global-method-security secured-annotations="enabled" />
@Secured("ROLE_ADMIN")
@RequestMapping(params = "onlyForAdmins")
public ModelAndView onlyForAdmins() {
....
}
Per @ Preautoryzuj Adnotację
Wymaga <global-method-security pre-post-annotations="enabled" />
@PreAuthorize("isAuthenticated()")
@RequestMapping(params = "onlyForAuthenticated")
public ModelAndView onlyForAuthenticatedUsers() {
....
}
Programmatic
SecurityContextHolder.getContext().getAuthentication() != null &&
SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
//when Anonymous Authentication is enabled
!(SecurityContextHolder.getContext().getAuthentication()
instanceof AnonymousAuthenticationToken)
Wyrażenie Własne
Jeśli wbudowane wyrażenia nie wystarczą, możesz je rozszerzyć. Jak rozszerzyć wyrażenia SpEL dla adnotacji metody jest omówione na przykład tutaj:
- Jak utworzyć niestandardowe metody do użycia w Spring security expression language adnotacje
- http://bmchild.blogspot.de/2012/02/creating-custom-regex-spring-security.html
Ale dla interceptor {[10] } jest nieco inne podejście możliwe, że nie trzeba radzić sobie z problemem klasy prywatnej. -- zrobiłem to tylko dla Spring Security 3.0, ale mam nadzieję, że zadziała również dla 3.1.
1.) musisz utworzyć nową klasę, która rozciąga się od WebSecurityExpressionRoot
(prefiks Web jest ważnym część!).
public class MyCustomWebSecurityExpressionRoot
extends WebSecurityExpressionRoot {
public MyCustomWebSecurityExpressionRoot(Authentication a,
FilterInvocation f) {
super(a, f);
}
/** That method is the one that does the expression evaluation! */
public boolean myCustomAuthenticatedExpression() {
return super.request.getSession().getValue("myFlag") != null;
}
}
2.) potrzebujesz rozszerzenia DefaultWebSecurityExpressionRootHandler
, aby mieć obsługę, która zapewnia root twojego wyrażenia niestandardowego
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public EvaluationContext createEvaluationContext(Authentication a,
FilterInvocation f) {
StandardEvaluationContext ctx =
(StandardEvaluationContext) super.createEvaluationContext(a, f);
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
ctx.setRootObject(myRoot);
return ctx;
}
}
3. Następnie musisz zarejestrować swojego opiekuna u wyborców
<security:http use-expressions="true"
access-decision-manager-ref="httpAccessDecisionManager" ...>
...
<security:intercept-url pattern="/restricted/**"
access="myCustomAuthenticatedExpression" />
...
</security:http>
<bean id="httpAccessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg name="decisionVoters">
<list>
<ref bean="webExpressionVoter" />
</list>
</constructor-arg>
</bean>
<bean id="webExpressionVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler"
ref="myCustomWebSecurityExpressionHandler" />
</bean>
<bean id="myCustomWebSecurityExpressionHandler"
class="MyCustomWebSecurityExpressionHandler" />
Spring Security 3.1 Update
Od wersji Spring Security 3.1 nieco łatwiej jest zaimplementować własne wyrażenie. Nie trzeba już podlinkować WebSecurityExpressionHandler
i nadpisywać createEvaluationContext
. Zamiast jednej podklasy AbstractSecurityExpressionHandler<FilterInvocation>
lub jej podklasy DefaultWebSecurityExpressionHandler
i nadpisać SecurityExpressionOperations createSecurityExpressionRoot(final Authentication a, final FilterInvocation f)
.
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public SecurityExpressionOperations createSecurityExpressionRoot(
Authentication a,
FilterInvocation f) {
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
myRoot.setPermissionEvaluator(getPermissionEvaluator());
myRoot.setTrustResolver(this.trustResolver);
myRoot.setRoleHierarchy(getRoleHierarchy());
return myRoot;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:02
Inne rozwiązanie, można sprawdzić principal w metodach kontrolera:
@Controller
@RequestMapping(value = "/promotion")
public final class PromotionController {
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public final String root(final Principal principal) {
if (null == principal) return "login"; // or some logic
// some logic
return "promotion/index";
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-03 19:49:24
Czy to właśnie próbujesz osiągnąć?
<c:choose>
<c:when test="${pageContext.request.userPrincipal.authenticated}">Show something</c:when>
<c:otherwise>Show something else</c:otherwise>
</c:choose>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-05 03:35:46