【发布时间】:2015-01-31 00:57:36
【问题描述】:
使用@RequestMapping,请求可以通过header或者request参数关联到不同的控制器函数。有没有办法根据用户用户角色来实现这一目标?目的是避免控制器中的 if 语句。
【问题讨论】:
-
在此处查看已接受的答案(以及其他各种建议):stackoverflow.com/questions/17995744/…
标签: spring-mvc spring-security
使用@RequestMapping,请求可以通过header或者request参数关联到不同的控制器函数。有没有办法根据用户用户角色来实现这一目标?目的是避免控制器中的 if 语句。
【问题讨论】:
标签: spring-mvc spring-security
根据用户角色实现AuthenticationSuccessHandler onAuthenticationSuccess 重定向到特定控制器。
【讨论】:
据我所知,没有任何开箱即用的功能,但如果您愿意,您可以创建自定义映射注释来为您执行此路由。
我实际上并没有尝试过任何代码,但类似:
你的新注解,类似@UserRoleMapping("ROLE_ADMIN")
@Target( ElementType.TYPE )
@Retention(RetentionPolicy.RUNTIME)
public @interface UserRoleMapping {
String[] value();
}
接下来,您可以扩展标准 Spring RequestMappingHandlerMapping 类(这是处理 @RequestMapping 注释的标准映射的类)。您只需要告诉映射处理程序也考虑自定义条件:
public class UserRoleRequestCondition extends RequestMappingHandlerMapping {
@Override protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
UserRoleMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, UserRoleMapping.class);
return (typeAnnotation != null) ? new UserRoleRequestCondition( typeAnnotation.value() ) : null;
}
}
上面的代码只是检查控制器是否有你在上面创建的新注解,如果找到它会返回一个新的条件类,使用你在注解中设置的值构造(例如“ROLE_ADMIN”)。此 MappingHandler 需要在您的 Spring 配置中设置(无论您当前设置 RequestMappingHandlerMapping 的位置,只需将其替换为其中之一即可)。
接下来我们需要创建自定义条件 - 这是将根据请求调用以确定请求是否与控制器匹配的人:
public class UserRoleRequestCondition implements RequestCondition<UserRoleRequestCondition> {
private final Set<String> roles;
public UserRoleRequestCondition( String... roles ) {
this( Arrays.asList(roles) );
}
public UserRoleRequestCondition( Collection<String> roles ) {
this.roles = Collections.unmodifiableSet(new HashSet<String>(roles));
}
@Override public UserRoleRequestCondition combine(UserRoleRequestCondition other) {
Set<String> allRoles = new LinkedHashSet<String>(this.roles);
allRoles.addAll(other.roles);
return new UserRoleRequestCondition(allRoles);
}
@Override public UserRoleRequestCondition getMatchingCondition( HttpServletRequest request ) {
UserRoleRequestCondition condition = null;
for (String r : roles){
if ( request.isUserInRole( r ) ){
condition = this;
}
}
return condition;
}
@Override public int compareTo(UserRoleRequestCondition other, HttpServletRequest request) {
return (other.roles - this.roles).size();
}
}
在上面,方法getMatchingCondition是我们匹配请求的地方。 (抱歉,如果我遗漏了一些分号或返回关键字等 - 这是基于 groovy,但希望如果你在 java 中,你可以找出这些位的去向!)
向 Marek 提供更详细的答案,让他更详细地回答了基于子域的自定义路由的更完整的解决方案,当我必须实现类似的东西时,我使用了该解决方案! How to implement @RequestMapping custom properties - 这提供了有关正在发生的事情的更多详细信息,以及如何拥有方法级别的注释(本示例跳过了这一点,只定义了类级别的注释)
我也在这里写了一些笔记:http://automateddeveloper.blogspot.co.uk/2014/12/spring-mvc-custom-routing-conditions.html
【讨论】: