如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?
Posted
技术标签:
【中文标题】如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?【英文标题】:How to Secure Spring Rest Services with Spring Sercurity and Angularjs? 【发布时间】:2014-04-13 22:19:28 【问题描述】:我有一个带有 Rest-Services 和 AngularJS WebFrontend 的 Spring MVC 服务器后端。
我想保护我的 spring mvc 休息服务,但我想使用 java config.. 我不知道配置应该是什么样子。有人可以帮我弄这个吗 ? 我发现的唯一好的实现是:https://github.com/philipsorst/angular-rest-springsecurity
我使用 postgrsDB,我想在那里存储用户名和密码以及角色,https://github.com/philipsorst/angular-rest-springsecurity 示例中的会话令牌是否仅存储在缓存中而不是数据库中?
目前我有一个简单的表单登录安全性,这仅用于测试,但我没有使用 jsp 我只使用 spring mvc 休息服务和 angularjs 作为 webfrontend.. 我如何修改我的 spring 安全代码它像 https://github.com/philipsorst/angular-rest-springsecurity 的示例中那样与 oauth2 一起使用?我目前只有这两个来自 spring security 的课程..
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth
.inMemoryAuthentication()
.withUser("username").password("test").roles("User");
然后我在我的 WebInitializer 中注册 securityConfig。
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
@Override
protected Class<?>[] getRootConfigClasses()
return new Class<?>[] PersistenceContext.class,AppConfig.class,SecurityConfig.class ;
....
但是角色和用户名/密码应该存储在数据库中。我必须使用特殊的数据库模式来实现 spring 安全性来在我的数据库中存储用户名、密码和角色吗?
我可以实现它,以便我只能在其中一个角色的其余服务上添加@Secured Annotation(或任何其他注释)吗?喜欢@Secured("UserRole")
还是更简单的基本认证?我可以通过角色管理的基本身份验证来保护我的休息服务!?如果是这样,我们可以使用基本身份验证.. 最好的问候
【问题讨论】:
【参考方案1】:为了加载用户,您必须创建一个身份验证管理器并将 UserDetailsService 连接到该身份验证管理器。以下文档链接很好地概述了身份验证管理器以及相关的核心组件。
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#core-services
所以,回答你的第一个问题……
但是角色和用户名/密码应该存储在数据库中.. 我必须使用特殊的 用于 Spring Security 的数据库模式,用于在我的数据库中存储用户名、密码和角色?
你可以做任何一个。如果您愿意,spring security 可以为您处理所有数据库端,您只需提供对具有 Spring 架构设计的 JDBC 数据源的引用。
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#core-services-jdbc-user-service
和
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#appendix-schema
-或-
您可以通过提供您自己的 UserDetailsService 实现来利用您自己的架构,该实现将从您自己的数据库架构中加载。这里有一些示例可以帮助您开始使用这种方法。
<context:component-scan base-package="com.example.security" />
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"/>
<bean id="dao-provider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"
p:userDetailsService-ref="myUserDetailsService"
p:passwordEncoder-ref="sha-pw-encoder"
p:saltSource-ref="my-salt-source" />
<bean id="sha-pw-encoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"
p:encodeHashAsBase64="true" />
<bean id="my-salt-source" class="org.springframework.security.authentication.dao.ReflectionSaltSource"
p:userPropertyToUse="salt" />
<security:authentication-manager>
<security:authentication-provider ref="dao-provider"/>
</security:authentication-manager>
最后,像这样提供 UserDetailsService 的实现:
@Component("myUserDetailsService")
public class MyUserDetailsServiceImpl implements UserDetailsService
//Reference to the spring JPA repository for loading users
private final UserRepository userRepository;
@Autowired
public MyUserDetailsServiceImpl(UserRepository userRepository)
this.userRepository = userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
User user = userRepository.findByName(username);
if (user != null)
return new UserDetails()
... //create the user details from the user object
else
String err = String.format("Failed to find username: %s in local database. Trying other auth mechanisms.", username);
throw new UsernameNotFoundException(err);
...关于你的第二个问题:
我可以实现它,以便我只能添加@Secured Annotation(或任何其他 注释)在我的其余服务中扮演角色之一吗?喜欢@Secured("UserRole")
是的,以上配置将允许您通过配置 global-method-security 来使用@Secured 注解。
最后,是的,所有这些默认情况下仍将使用基本身份验证,但如有必要,可以重新配置为使用摘要身份验证。我建议完整阅读http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/ 的文档,以便真正掌握您想要做什么。但是,这应该会让你上路。
【讨论】:
嗯,我的项目中没有使用 JPA,也没有 xml 文件。安全模式不太好我不希望用户名作为主键我想要一个普通的 ID 作为整数,然后是用户名密码。 Hoq 我可以将上面的 xml 转换为 java 吗? 我使用 Jooq 作为我的数据库映射层jooq.org 并且没有 JPA 或 DAO,但 jooq 可以生成 DAOS 但我不知道这是否适用于 spring.. 我可以在没有 JPA 的情况下进行用户服务吗?我该如何转换:“bean id="dao-provider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider" p:userDetailsService-ref="myUserDetailsService" p:passwordEncoder-ref="sha-pw-编码器" p:saltSource-ref="my-salt-source" />" 到我没有 JPA 的 Jooq 实现? 对不起,我不知何故错过了你一开始在做 Java 配置......所以,你应该能够做到以下几点: 1) 按照我上面的建议创建 UserDetailsService 实现。 2) 代替 auth.inMemoryAuthentication() 调用 auth.userDetailsService(myUserDetailsService),传入您自己的用户详细信息服务参考。 3)您可以让您的 UserDetailsService 使用您想要加载用户名的任何方法,是否使用 jooq 应该是无关紧要的,只要您可以加载用户对象,然后将您的用户格式转换为 UserDetails 对象,这就是是必需的。 你能做一个这样的 UserDetails 对象的例子吗?我有 2 个表,其中一个是具有 id(作为主键)、用户名、密码和 role_ID 作为外键的帐户。第二个表是roles_lookup,其中role_id 作为主键和rolename。在表中role_lookup 是role_id 1 =“admin”和role_id 2 =“user”。 Account Table 中的 Foreignt Key 链接到 roles_lookup 表。我可以将此 Tabes 用于 userdetailsservice 吗?如何使用 jdbc 和我的表创建用户对象?以上是关于如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config
如何使用spring-security通过用户名和密码登录?
spring-security 开启注解权限控制为什么没有效果
如何使用 spring-security 和 jQuery 处理过期会话?