我试图使用Shiro Annotations进行权限检查,将Spring Shi(2.0.4)应用程序中的Apache Shiro与JDBC领域和Jersey REST集成在一起。但是,只有sauth身份验证部分有效,shiro不会在注释上调用授权。
我的Shiro配置如下:
@Bean(name = "realm")
@DependsOn("lifecycleBeanPostProcessor")
public JdbcRealm jdbcRealm() {
MyJDBCRealm realm = new MyJDBCRealm();
Sha256CredentialsMatcher credentialsMatcher = new Sha256CredentialsMatcher();
credentialsMatcher.setStoredCredentialsHexEncoded(false);
credentialsMatcher.setHashIterations(1024);
realm.setCredentialsMatcher(credentialsMatcher);
realm.setAuthenticationQuery("SELECT password, salt FROM User WHERE email = ?");
realm.setPermissionsLookupEnabled(true);
realm.setUserRolesQuery("select roleName from UserRole where email = ?");
realm.setPermissionsQuery("select permission from RolesPermission where roleName = ?");
realm.init();
return realm;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(jdbcRealm());
return securityManager;
}
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// use permissive to NOT require authentication, our controller Annotations will decide that
//chainDefinition.addPathDefinition("/**", "authcBasic[permissive]");
chainDefinition.addPathDefinition("/**", "authcBasic");
return chainDefinition;
}
@Bean(name = "shiroFilter")
public AbstractShiroFilter shiroFilter() throws Exception {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager());
Map<String, String> filterChainDefinitionMapping = new HashMap<>();
filterChainDefinitionMapping.put("/**", "authcBasic");
shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMapping);
Map<String, Filter> filters = new HashMap<>();
filters.put("anon", new AnonymousFilter());
filters.put("authcBasic", new BasicHttpAuthenticationFilter());
filters.put("authcBasicRoles", new RolesAuthorizationFilter());
filters.put("authcBasicPermissions", new PermissionsAuthorizationFilter());
shiroFilter.setFilters(filters);
return (AbstractShiroFilter) shiroFilter.getObject();
}
@Bean (name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
@ConditionalOnMissingBean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultSecurityManager securityManager) {
// This is to enable Shiro's security annotations
AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();
sourceAdvisor.setSecurityManager(securityManager);
return sourceAdvisor;
}
@ConditionalOnMissingBean
@Bean(name = "defaultAdvisorAutoProxyCreator")
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
@Bean
public CacheManager cacheManager() {
// Caching isn't needed in this example, but we will use the MemoryConstrainedCacheManager for this example.
return new MemoryConstrainedCacheManager();
}
使用上面的代码,Shiro进行了身份验证,但是它涉及到Jersey REST控制器,它不会在Shiro注释上调用授权
@POST
@Path("/authorize/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequiresPermissions("service:create")
public Session register(UserInfo inputData) throws AppException{.......
如果有人可以让我知道我缺少什么来进行这项工作将会很有帮助。
根据要求为MyJDBCRealm添加代码。
@Component 公共类MyJDBCRealm扩展了JdbcRealm {
@Autowired
UserManagerDAO userManagerDAO;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// identify account to log to
UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
final String username = userPassToken.getUsername();
if (username == null) {
System.out.println("Username is null.");
return null;
}
// read password hash and salt from db
final User user = userManagerDAO.getUserByEmail(username);
if (user == null) {
System.out.println("No account found for user [" + username + "]");
return null;
}
// return salted credentials
SaltedAuthenticationInfo info = new MySaltedAuthentication(username, user.getPassword(), user.getSalt());
return info;
}
}
我还向您提供了我在此Spring boot 2.0.4应用程序中使用的shiro pom依赖项。请注意,使用的Spring引导版本是2.0.4,使用的是Jersey 2.26版本。由于某些注入实现问题,我在某处读到2.26 jersey版本不适用于shiro注释。但是,如果我将jersey降级到2.25,则一些春季bean注入会停止工作,并且服务器在启动时崩溃。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0-RC2</version>
</dependency>