Spring security如何设置只有用户登录才能访问一些资源

MLGKO 发布于 2015/04/17 13:18
阅读 6K+
收藏 0

我在数据库中有一些资源没有配置到角色上面,所以只要用户登录就能访问一些资源,但是我在spring配置文件里面配置了下面的配置就算没有登录也可以访问一些在数据库中没有配置到角色上的资源

<intercept-url pattern="/**" access="isAuthenticated()"  />还有

<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/> 还有

<intercept-url pattern="/**" access="ROLE_USER" />在没有登录的情况下还是可以访问的,是不是因为我自定义访问决策器(

AccessDecisionManager

)和自定义

FilterInvocationSecurityMetadataSource

这个两个类的问题??



这个是AccessDecisionManager的实现

public class AccessDecisionManagerService implementsAccessDecisionManager {

public AccessDecisionManagerService(){

}

/**

* 其中两个重写的suppots方法都把返回值改为true

* 最重要的就是decide方法 ,它负责去决策你是否有权限去访问你访问的资源。

* 这个方法的第一个参数Authentication 是你登陆的角色所具有的权限列表。

* 第二个参数是你访问的url

* 第三个参数是访问这个url所需要的权限列表。

*/

@Override

public void decide(Authentication authentication, Object object,

Collection<ConfigAttribute> configAttributes)

throws AccessDeniedException, InsufficientAuthenticationException {

Collection<? extends GrantedAuthority>authorities=authentication.getAuthorities();//用户所具有的角色

if(configAttributes==null){//访问的当前资源没有权限限定,可以任意访问

return;

}

if(authorities==null||authorities.isEmpty()){

throw new AccessDeniedException("无权限");

}

for(GrantedAuthority authority:authorities){

String roleName=authority.getAuthority();

for(ConfigAttribute needRole:configAttributes){

if(roleName.equals(needRole.getAttribute())){

return;

}

}

}

org.springframework.security.web.DefaultSecurityFilterChain ;

throw new AccessDeniedException("无权限");

}

@Override

public boolean supports(ConfigAttribute attribute) {

// MFE Auto-generated method stub

return true;

}

@Override

public boolean supports(Class<?> clazz) {

// MFE Auto-generated method stub

return true;

}


}



这个是

FilterInvocationSecurityMetadataSource的实现

public class SecurityMetadataSourceService implements

FilterInvocationSecurityMetadataSource {

private static final Log LOG = LogFactory.getLog(FilterInvocationSecurityMetadataSource.class);

@Autowired

private PermissionService permissionService;

@Autowired

private RoleService roleService;

/**

* 权限容器

* key:URL

* value:角色

*/

private static final Map<String,Collection<ConfigAttribute>> LIMIT =new HashMap<String,Collection<ConfigAttribute>>();//存储所有角色的权限

@Override

public Collection<ConfigAttribute> getAttributes(Object object)

throws IllegalArgumentException {

String accessURL = ((FilterInvocation)object).getRequestUrl();

LOG.debug("访问地址:"+accessURL);

return LIMIT.get(accessURL);

}


@Override

public Collection<ConfigAttribute> getAllConfigAttributes() {

return null;

}


@Override

public boolean supports(Class<?> clazz) {

return true;

}

@SuppressWarnings({ "unused""serial" })

private void loadPermissionDefind(){

LOG.debug("正在初始化资源中");

List<Authority> authorities = permissionService.loadAuthority();

for(int i=0;i<authorities.size();i++){

final Authority authority=authorities.get(i);

String serverURL = authority.getServerURL();

LOG.info("初始化角色:"+authority.getRoleKey()+",资源:"+serverURL);

if(LIMIT.containsKey(serverURL)){

LIMIT.get(serverURL).add(newSecurityConfig(authority.getRoleKey()));

continue;

}

LIMIT.put(authority.getServerURL(),new ArrayList<ConfigAttribute>(){

{

add(new SecurityConfig(authority.getRoleKey()));

}

});

}

LOG.info("ALL LIMIT IS "+JSONObject.fromObject(LIMIT));

LOG.debug("初始化资源完成");

}

}



web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" 

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"version="2.5" 

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 


  <display-name>Security Plugin</display-name>

  

  <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>

        classpath:application-context.xml,

        classpath:application-context-hibernate.xml,

        classpath:application-context-security.xml

     </param-value>

  </context-param>

  

  <context-param>

    <param-name>webAppRootKey</param-name>

    <param-value>security.root</param-value>

  </context-param>

  <context-param>

    <param-name>log4jConfigLocation</param-name>

    <param-value>classpath:log4j.xml</param-value>

  </context-param>

  

  <context-param>

    <param-name>log4jExposeWebAppRoot</param-name>

    <param-value>true</param-value>

  </context-param>


  <context-param>

    <param-name>log4jRefreshInterval</param-name>

    <param-value>60000</param-value>

  </context-param>

  <filter>

  <filter-name>springSecurityFilterChain</filter-name>

  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

  </filter>

  <filter-mapping>

  <filter-name>springSecurityFilterChain</filter-name>

  <url-pattern>/*</url-pattern>

  </filter-mapping>

  <filter>

    <filter-name>characterEncodingFilter</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

      <param-name>encoding</param-name>

      <param-value>utf-8</param-value>

    </init-param>

  </filter>

  <filter-mapping>

    <filter-name>characterEncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

  <listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <listener>

    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

  </listener>

  <!-- spring security限制用户的登陆(单次登陆) -->

  <listener>

  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

  </listener>

  <servlet>

    <servlet-name>securityManager</servlet-name>

    <servlet-class>

      org.springframework.web.servlet.DispatcherServlet

    </servlet-class>

    <init-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/spring/securityManager-servlet.xml</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

    <servlet-name>securityManager</servlet-name>

    <url-pattern>/</url-pattern>

  </servlet-mapping>

</web-app>


加载中
0
逝水fox
逝水fox
最好把配置(web.xml里面加的安全过滤器,Spring的这块配置)全部贴出来

另外,多个<intercept-url>,默认的处理是按配置顺序检查的,一旦匹配,就用该项的,后面的即使能匹配也不会生效。

如果自定义了什么东西,就说来话长了,特别是AccessDecisionManager,不知道你怎么写的,不过个人觉得如果要自定义,最好详细看完官方文档,清楚他每一步是怎么工作的

0
MLGKO
MLGKO
自己顶一下
0
MLGKO
MLGKO
自己顶一下,千万别沉底
0
MLGKO
MLGKO
大神在哪里
0
MLGKO
MLGKO
大神在哪里高速我下吧
0
MLGKO
MLGKO

这个是AccessDecisionManager的实现

public class AccessDecisionManagerService implements AccessDecisionManager {

public AccessDecisionManagerService(){

}

/**

* 其中两个重写的suppots方法都把返回值改为true

* 最重要的就是decide方法 ,它负责去决策你是否有权限去访问你访问的资源。

* 这个方法的第一个参数Authentication 是你登陆的角色所具有的权限列表。

* 第二个参数是你访问的url

* 第三个参数是访问这个url所需要的权限列表。

*/

@Override

public void decide(Authentication authentication, Object object,

Collection<ConfigAttribute> configAttributes)

throws AccessDeniedException, InsufficientAuthenticationException {

Collection<? extends GrantedAuthority> authorities=authentication.getAuthorities();//用户所具有的角色

if(configAttributes==null){//访问的当前资源没有权限限定,可以任意访问

return;

}

if(authorities==null||authorities.isEmpty()){

throw new AccessDeniedException("无权限");

}

for(GrantedAuthority authority:authorities){

String roleName=authority.getAuthority();

for(ConfigAttribute needRole:configAttributes){

if(roleName.equals(needRole.getAttribute())){

return;

}

}

}

org.springframework.security.web.DefaultSecurityFilterChain ;

throw new AccessDeniedException("无权限");

}

@Override

public boolean supports(ConfigAttribute attribute) {

// MFE Auto-generated method stub

return true;

}

@Override

public boolean supports(Class<?> clazz) {

// MFE Auto-generated method stub

return true;

}


}



这个是

FilterInvocationSecurityMetadataSource的实现

public class SecurityMetadataSourceService implements

FilterInvocationSecurityMetadataSource {

private static final Log LOG = LogFactory.getLog(FilterInvocationSecurityMetadataSource.class);

@Autowired

private PermissionService permissionService;

@Autowired

private RoleService roleService;

/**

* 权限容器

* key:URL

* value:角色

*/

private static final Map<String,Collection<ConfigAttribute>> LIMIT = new HashMap<String,Collection<ConfigAttribute>>();//存储所有角色的权限

@Override

public Collection<ConfigAttribute> getAttributes(Object object)

throws IllegalArgumentException {

String accessURL = ((FilterInvocation)object).getRequestUrl();

LOG.debug("访问地址:"+accessURL);

return LIMIT.get(accessURL);

}


@Override

public Collection<ConfigAttribute> getAllConfigAttributes() {

return null;

}


@Override

public boolean supports(Class<?> clazz) {

return true;

}

@SuppressWarnings({ "unused", "serial" })

private void loadPermissionDefind(){

LOG.debug("正在初始化资源中");

List<Authority> authorities = permissionService.loadAuthority();

for(int i=0;i<authorities.size();i++){

final Authority authority=authorities.get(i);

String serverURL = authority.getServerURL();

LOG.info("初始化角色:"+authority.getRoleKey()+",资源:"+serverURL);

if(LIMIT.containsKey(serverURL)){

LIMIT.get(serverURL).add(new SecurityConfig(authority.getRoleKey()));

continue;

}

LIMIT.put(authority.getServerURL(),new ArrayList<ConfigAttribute>(){

{

add(new SecurityConfig(authority.getRoleKey()));

}

});

}

LOG.info("ALL LIMIT IS "+JSONObject.fromObject(LIMIT));

LOG.debug("初始化资源完成");

}

}



web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" 

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" 

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 


  <display-name>Security Plugin</display-name>

  

  <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>

        classpath:application-context.xml,

        classpath:application-context-hibernate.xml,

        classpath:application-context-security.xml

     </param-value>

  </context-param>

  

  <context-param>

    <param-name>webAppRootKey</param-name>

    <param-value>security.root</param-value>

  </context-param>

  <context-param>

    <param-name>log4jConfigLocation</param-name>

    <param-value>classpath:log4j.xml</param-value>

  </context-param>

  

  <context-param>

    <param-name>log4jExposeWebAppRoot</param-name>

    <param-value>true</param-value>

  </context-param>


  <context-param>

    <param-name>log4jRefreshInterval</param-name>

    <param-value>60000</param-value>

  </context-param>

  <filter>

  <filter-name>springSecurityFilterChain</filter-name>

  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

  </filter>

  <filter-mapping>

  <filter-name>springSecurityFilterChain</filter-name>

  <url-pattern>/*</url-pattern>

  </filter-mapping>

  <filter>

    <filter-name>characterEncodingFilter</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

      <param-name>encoding</param-name>

      <param-value>utf-8</param-value>

    </init-param>

  </filter>

  <filter-mapping>

    <filter-name>characterEncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

  <listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <listener>

    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

  </listener>

  <!-- spring security限制用户的登陆(单次登陆) -->

  <listener>

  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

  </listener>

  <servlet>

    <servlet-name>securityManager</servlet-name>

    <servlet-class>

      org.springframework.web.servlet.DispatcherServlet

    </servlet-class>

    <init-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/spring/securityManager-servlet.xml</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

    <servlet-name>securityManager</servlet-name>

    <url-pattern>/</url-pattern>

  </servlet-mapping>

</web-app>

0
MLGKO
MLGKO
自己顶下,千万别沉
0
MLGKO
MLGKO
自己顶下千万别沉,别沉,别沉底
0
Catelyn
Catelyn

你都自定义了FilterInvocationSecurityMetadataSource了,我看你是读的数据库来初始化url和role的对应集合的,所以它就不读配置文件了,默认是读xml来获取这些信息的!

0
MLGKO
MLGKO
谢谢,这个已经解决了
寂寞不痛
寂寞不痛
楼主解决了不把方法贴出来?
返回顶部
顶部