2012-06-29 1 views
1

Я пытаюсь повысить безопасность веб-приложения с поддержкой Spring, используя Apache Shiro, и таким образом настраиваю определения фильтров в конфигурационный файл с пружиной. Как я достичь эквивалентаShiro Spring с определениями фильтров, эквивалентными для @RequiresRoles logical.OR

@Controller 
@RequestMapping("/mywebapp") 
// @RequiresAuthentication (is this possible ? wish i could do this !) 
public class MyWebAppController { 

@RequiresRoles(value={"Role1","Role2","Role3"},logical=Logical.OR) 
@RequestMapping(value="/home", method = RequestMethod.GET) 
public String home() { return .. } 

и мой файл пружинно-конфигурации содержит следующее: предположить, что мой DispatcherServlet сопоставляется/отдыха/*

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
    <property name="securityManager" ref="securityManager"/> 
    <property name="loginUrl" value="/rest/secure/windowslogin"/> 
    <property name="successUrl" value="/mywebapp/rest/menu"/> 
    <property name="unauthorizedUrl" value="/mywebapp/rest/unauthorized"/> 
    <property name="filters"> 
     <util:map> 
      <entry key="anon"> 
       <bean class="org.apache.shiro.web.filter.authc.AnonymousFilter"/> 
      </entry> 
      <entry key="authc"> 
     <!-- why is this not invoked ? --> 
       <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"> 
       </bean> 
      </entry> 
      <entry key="roles"> 
       <bean class="org.apache.shiro.web.filter.authz.RolesAuthorizationFilter"/> 
      </entry> 
     </util:map> 
    </property> 
    <property name="filterChainDefinitions"> 
     <value> 
      /rest/secure/** = anon 
      /rest/mywebapp/** = authc, roles[Role1,Role2,Role3] 
     </value> 
    </property> 
</bean> 

В коде выше я нужен logical.OR вид отображения в /rest/mywebapp/** с использованием упомянутых ролей. Это возможно с помощью аннотаций siro, и это работает, но вместо того, чтобы указывать при каждом методе, я бы лучше справился с этим здесь (так как я не думаю, что siro поддерживает аннотации уровня класса еще?). Возможно ли это?

Также на боковой ноте почему фильтр authc не вызывается? (на данный момент мы предполагаем, что окна Логин может служить в качестве аутентификации, используя Shiro только для авторизации)

home page = meta refresh to /rest/secure/windowslogin/ 
      if within intranet -> login ... 
      else /rest/secure/login ... login page. 

Это потому, что loginurl отличается? Как мне обойти это? Обратите внимание, что getAuthorizationInfo моей реальности вызывается, используя часть роли [..], указанную в файле конфигурации. Но я предполагал, что должна быть проверка, чтобы проверить, является ли запрос «authc»? (что, вероятно, означает, что фильтр вызывается, а SubjectUtils.getSubject() проверяется для аутентификации). Я что-то пропустил в потоке или конфигурации?

ответ

1

Как выглядит shiro-security.xml.

<bean id="customFilter1" class="com.pkg.RolesAuthorizationFilter"> 
     <property name="roles" value="ROLE1,ROLE3,ROLE5"></property> 
</bean> 
<bean id="customFilter2" class="com.pkg.RolesAuthorizationFilter"> 
     <property name="roles" value="ROLE1,ROLE2,ROLE5,ROLE6"></property> 
</bean> 

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
     <property name="securityManager" ref="securityManager" /> 
     <property name="loginUrl" value="/login" /> 
     <property name="successUrl" value="/home" /> 
     <property name="unauthorizedUrl" value="/unauthorized" />  
    <property name="filters"> 
     <util:map> 
      <entry key="authc"> 
       <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" /> 
      </entry> 
     </util:map> 
    </property> 

<property name="filterChainDefinitions"> 
      <value> 
      /resources/** = anon 
       /login = anon 
       /logout = authc    
       /unauthorized = authc 
       /someurl/** = customFilter2 
       /** = customFilter1 
      </value> 
     </property> 
</bean> 

И это RolesAuthorizationFilter класс

package com.pkg; 

import java.util.Arrays; 

import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 

import org.apache.log4j.Logger; 
import org.apache.shiro.subject.Subject; 
import org.apache.shiro.web.filter.authz.AuthorizationFilter; 

public class RolesAuthorizationFilter extends AuthorizationFilter { 
    protected Logger logger = Logger.getLogger(this.getClass() 
      .getCanonicalName()); 

    private String[] roles; 

    @Override 
    protected boolean isAccessAllowed(ServletRequest request, 
      ServletResponse response, Object mappedValue) throws Exception { 

     logger.info("= Roles = " + Arrays.toString(roles)); 

     Subject subject = getSubject(request, response); 
     boolean allowAccess = false; 

     for (String role : roles) { 
      if (subject.hasRole(role)) { 

       logger.info("Authenticated role " + role); 

       allowAccess = true; 
       break; 
      } 
     } 

     return allowAccess; 
    } 

    public void setRoles(String[] roles) { 
     this.roles = roles; 
    } 
}