来自@PreAuthorize的hasRole从哪里获取其在Spring中的值?

时间:2015-05-29 08:12:16

标签: java spring spring-mvc spring-security

您好我是Spring的新手,我正在尝试更多地了解安全模型。 在我们的项目中,我们控制哪个方法用

注释
@PreAuthorize("hasRole('REPORT_VIEW')")

所以我想知道这个REPORT_VIEW来自哪里是ENUM还是基于某些xml配置?我在文件中搜索,但我找不到REPORT_VIEW作为单词。

从这里: http://www.mkyong.com/spring-security/spring-security-access-control-example/

我看到配置security-context.xml在哪里

<user-service>
        <user name="mkyong" password="password" authorities="ROLE_USER" />
        <user name="eclipse" password="password" authorities="ROLE_ADMIN" />
</user-service>

在我的项目中

<sec:authentication-manager>
        <sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>

<bean id="clientDetailsUserService"
        class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <constructor-arg ref="clientDetails" />
</bean>

所以我作为开发人员想要创建一些控制器,从哪里了解哪些是应用程序的角色?

2 个答案:

答案 0 :(得分:2)

我可以通过XML文件和一些Java代码向您解释。这是我如何登录并分配角色。您还可以在DB中查询角色。

security-applicationContext.xml:

 <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="LoginServiceImpl">
           <security:password-encoder  ref="encoder"/>
        </security:authentication-provider>
    </security:authentication-manager>


    <beans:bean id="daoAuthenticationProvider"
                class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                <beans:property name="userDetailsService" ref="LoginServiceImpl"/>
               <beans:property name="passwordEncoder" ref="encoder"/>
    </beans:bean>

上面是我的数据库身份验证代码,它引用了LoginServiceImpl的bean,我从DB中搜索用户。模型类已实现UserDetails。

LoginServiceImpl:

@Transactional
@Service("userDetailsService")
public class LoginServiceImpl implements UserDetailsService{

    @Autowired private PersonDAO personDAO;
    @Autowired private Assembler assembler;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
        Person person = personDAO.findPersonByUsername(username.toLowerCase());
            if(person == null) { throw new UsernameNotFoundException("Wrong username or password");}
        return assembler.buildUserFromUserEntity(person);
    }

    public LoginServiceImpl() {
    }
}

当在DB中找到用户时,我正在构建一个可以由spring-security用于会话的对象。这是怎么回事:

@Service("assembler")
public class Assembler {
    @Transactional(readOnly = true)
    User buildUserFromUserEntity(Person userEntity){
        String username = userEntity.getUsername().toLowerCase();
        String password = userEntity.getPassword();

        boolean enabled = userEntity.isEnabled();
        boolean accountNonExpired = userEntity.isAccountNonExpired();
        boolean credentialsNonExpired = userEntity.isCredentialsNonExpired();
        boolean accountNonLocked = userEntity.isAccountNonLocked();

        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        return new User(username,password,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,authorities);
        }
}

正如您所看到的,我正在添加角色,但我也可以查询数据库或您找到的任何其他逻辑,然后交出它,用户将拥有该角色。理想情况下,Person模型类应该具有到Role类的一对多映射,以及其中的用户角色。 如果这不是你想要的,我会删除我的答案,只是让我知道。

答案 1 :(得分:1)

Spring安全性的功能并非如此微不足道,但我试着解释一下:

Spring安全认证基于org.springframework.security.core.userdetails.UserDetails,它是用户的春天抽象。 UserDetailsGrantedAuthority个,可以是权限,角色或任何其他&#34; SecurityItem&#34;你的申请。 hasRole检查当前用户是否在表达式中包含GrantedAuthority名称(例如&#39; REPORT_VIEW&#39;)。

但这些UserDetails来自何处。这取决于您的应用程序。这是由实现org.springframework.security.core.userdetails.UserDetailsService的类提供的。这是应用程序的特定用户存储所挂钩的位置.Spring提供了一些实现UserDetailsService的实现,但您也可以实现自己的(例如,如果您将用户凭据存储在自定义数据库中)。

在您链接的示例中,UserDetailsService是基于XML创建和配置的(最简单的变体)。在您的应用程序中,UserDetails是通过OAuth2提供的,如果是,则在名为clientDetails的bean中定义,但您没有提供。