2017-01-18 687 views
0

我有一個只是API端點的服務器,沒有客戶端前端,沒有jsp,沒有html。它使用Spring Boot,我試圖用Shiro來保護它。我的SpringBootServletInitializer的相關部分看起來像這樣。我試圖讓Shiro在BasicRealm中定義的角色查找失敗時返回403響應。但它似乎默認重定向到一個不存在的login.jsp,而不管我似乎使用什麼解決方案。我無法重寫。任何幫助將不勝感激。如何使Shiro返回403禁止使用Spring Boot而不是重定向到login.jsp

@SpringBootApplication 
public class RestApplication extends SpringBootServletInitializer { 

    ... 

    @Bean(name = "shiroFilter") 
    public ShiroFilterFactoryBean shiroFilter() { 
     ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); 


     Map<String, String> filterChain = new HashMap<>(); 
     filterChain.put("/admin/**", "roles[admin]"); 

     shiroFilter.setFilterChainDefinitionMap(filterChain); 
     shiroFilter.setSecurityManager(securityManager()); 

     return shiroFilter; 
    } 

    @Bean 
    public org.apache.shiro.mgt.SecurityManager securityManager() { 
     DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 
     securityManager.setRealm(userRealm()); 

     CookieRememberMeManager rmm = new CookieRememberMeManager(); 
     rmm.setCipherKey(Base64.decode("XXXXXXXXXXXXXXXXXXXXXX")); 
     securityManager.setRememberMeManager(rmm); 

     return securityManager; 
    } 

    @Bean(name = "userRealm") 
    @DependsOn("lifecycleBeanPostProcessor") 
    public BasicRealm userRealm() { 
     return new BasicRealm(); 
    } 

    @Bean 
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { 
     return new LifecycleBeanPostProcessor(); 
    } 
} 

public class BasicRealm extends AuthorizingRealm { 
    private static Logger logger = UserService.logger; 
    private static final String REALM_NAME = "BASIC"; 

    public BasicRealm() { 
     super(); 
    } 

    @Override 
    protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) 
      throws AuthenticationException { 
     UsernamePasswordToken upToken = (UsernamePasswordToken) token; 
     String userid = upToken.getUsername(); 

     User user = Global.INST.getUserService().getUserById(userid); 

     if (user == null) { 
      throw new UnknownAccountException("No account found for user [" + userid + "]"); 
     } 

     return new SimpleAuthenticationInfo(userid, user.getHashedPass().toCharArray(), REALM_NAME); 
    } 

    @Override 
    protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) { 

     String userid = (String) principals.getPrimaryPrincipal(); 

     if (userid == null) { 
      return new SimpleAuthorizationInfo(); 
     } 

     return new SimpleAuthorizationInfo(Global.INST.getUserService().getRoles(userid)); 
    } 
} 

回答

0

好的,這裏是我如何解決它。我創建了一個類...

public class AuthFilter extends RolesAuthorizationFilter { 
    private static final String MESSAGE = "Access denied."; 

    @Override 
    protected boolean onAccessDenied(final ServletRequest request, final ServletResponse response) throws IOException { 
     HttpServletResponse httpResponse ; 
     try { 
      httpResponse = WebUtils.toHttp(response); 
     } 
     catch (ClassCastException ex) { 
      // Not a HTTP Servlet operation 
      return super.onAccessDenied(request, response) ; 
     } 

     if (MESSAGE == null) { 
      httpResponse.sendError(403); 
     } else { 
      httpResponse.sendError(403, MESSAGE); 
     } 
     return false; // No further processing. 
    } 
} 

...然後在我的shiroFilter()以上我方法添加此代碼...

Map<String, Filter> filters = new HashMap<>(); 
filters.put("roles", new AuthFilter()); 
shiroFilter.setFilters(filters); 

...希望這可以幫助別人。