Подтвердить что ты не робот

Spring MVC - проверка того, что пользователь уже зарегистрирован через Spring Безопасность?

У меня есть приложение Spring MVC. Он использует свою собственную страницу входа. При успешном входе в HTTPSession помещается объект LOGGED_IN_USER.

Я хочу разрешить только аутентифицированным пользователям доступ к URL-адресам. Я знаю, что могу добиться этого, используя веб-фильтр. Но, эта часть, которую я хочу использовать с помощью Spring Security (мой чек останется прежним - найдите объект LOGGED_IN_USER в HTTPSession, если он присутствует в вашем аккаунте).

Мое ограничение заключается в том, что я не могу изменить поведение входа в настоящее время - это еще не будет использовать Spring Безопасность.

Какой аспект безопасности Spring я могу использовать для достижения этой части в одиночку - проверить, проверен ли запрос (от входа в систему пользователя)?

4b9b3361

Ответ 1

Существует не менее 4 различных способов:

spring Конфигурация безопасности XML

это самый простой способ

<security:http auto-config="true" use-expressions="true" ...>
   ...
  <security:intercept-url pattern="/forAll/**" access="permitAll" />
  <security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>

Per @Secured Annotation

требуется <global-method-security secured-annotations="enabled" />

@Secured("ROLE_ADMIN")
@RequestMapping(params = "onlyForAdmins")    
public ModelAndView onlyForAdmins() {
    ....
}

Per @PreAuthorize Annotation

требуется <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) 

Пользовательское выражение

Если встроенных выражений недостаточно, вы можете их расширить. Расширение выражений SpEL для аннотаций метода обсуждается здесь:

Но для перехватчика <security:intercept-url ... access="myCustomAuthenticatedExpression" /> возможен несколько иной подход, который не требует решения проблемы частного класса. - Я только сделал это для spring Security 3.0, но я надеюсь, что он тоже работает для 3.1.

1.) вам нужно создать новый класс, который простирается от WebSecurityExpressionRoot (префикс Web - важная часть!).

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.) вам нужно расширить DefaultWebSecurityExpressionRootHandler, чтобы иметь обработчик, который предоставляет свой собственный пользовательский корень выражения

 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.) Затем вам нужно зарегистрировать своего обработчика с избирателями

<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 Обновление безопасности 3.1

Так как spring Security 3.1, это немного проще реализовать пользовательское выражение. Больше не требуется подкаска WebSecurityExpressionHandler и переопределить createEvaluationContext. Вместо этого один подкласс AbstractSecurityExpressionHandler<FilterInvocation> или его подкласс DefaultWebSecurityExpressionHandler и переопределить 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;
      }
 }

Ответ 2

Другое решение, вы можете проверить принцип в методах контроллера:

@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";
    }
}

Ответ 3

Это то, чего вы пытаетесь достичь?

<c:choose>
  <c:when test="${pageContext.request.userPrincipal.authenticated}">Show something</c:when>
  <c:otherwise>Show something else</c:otherwise>
</c:choose>