spring - 具有Openid和数据库集成的Spring Security

标签 spring openid spring-security

我是Spring和Spring Security的新手,希望有人可以帮助我解决以下问题。

我要实现的是在OpenID提供者(gmail)成功验证该用户后,提取该用户的用户名和电子邮件地址,然后与数据库进行检查,以便为该用户加载用户模型。

在我的spring-security.xml中,我有

<?xml版本=“1.0”编码=“UTF-8”?>

xmlns:tx =“http://www.springframework.org/schema/tx” xmlns:context =“http://www.springframework.org/schema/context” xmlns:security =“http://www.springframework .org / schema / security”
xsi:schemaLocation =“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd“>








<安全性:http>


login-page =“/ krams / auth / login” authentication-failure-url =“/ krams / auth / login?error = true”>














我的问题是在UserDetailsS​​erviceOpenIDImpl.java是

公共(public)类UserDetailsS​​erviceOpenIDImpl实现UserDetailsS​​ervice {

公共(public)UserDetails loadUserByUsername(字符串用户名)
引发UsernameNotFoundException,DataAccessException {
System.out.println(用户名);
//提取用户名和电子邮件地址,如何?
}
}

打印语句打印出类似

https://www.google.com/accounts/o8/id?id=AItOawlq2C3EdFAuqp-ski_xkgB8jsEKbe-mZE

我的问题是

(1)如何从返回的URL中提取用户名和电子邮件地址(而且,我什至不确定用户名和电子邮件地址是否正确返回)?

(2)通过在Eclipse上运行调试,似乎在返回URL(https://www.google.com/accounts/o8/id?id=AItOawlq2C3EdFAuqp-ski_xkgB8jsEKbe-mZE)时未调用YouEatAuthenticationSuccessHandler。

谢谢。

编辑:
感谢链接http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-openid

它说:“属性值作为身份验证过程的一部分返回,之后可以使用以下代码进行访问:...”

我已经添加了

OpenIDAuthenticationToken token =(OpenIDAuthenticationToken)SecurityContextHolder.getContext()。getAuthentication();
列出属性= token.getAttributes();

进入loadUserByUsername方法。但是“ token ”对象为空。

编辑2
通过跟随https://fisheye.springsource.org/browse/spring-security/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml?hb=true页面,我可以为用户添加名称和电子邮件地址。
我的spring-security.xml

<?xml版本=“1.0”编码=“UTF-8”?>
xmlns:tx =“http://www.springframework.org/schema/tx” xmlns:context =“http://www.springframework.org/schema/context” xmlns:security =“http://www.springframework .org / schema / security”
xsi:schemaLocation =“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd“>





<安全性:登出
invalidate-session =“true”
logout-success-url =“/ krams / auth / login”
logout-url =“/ krams / auth / logout” />
user-service-ref =“registeringUserService”
login-page =“/ krams / auth / login”
authentication-failure-url =“/ krams / auth / login?error = true”
default-target-url =“/ krams / main / common”>











->


自定义UserDetailsS​​ervice,它将允许任何用户在内部映射中认证和“注册”其ID
返回他们的网站时使用。对于使用OpenID的网站,这是最常见的使用模式。
->



我的CustomUserDetailsS​​ervice.java

公共(public)类CustomUserDetailsS​​ervice实现AuthenticationUserDetailsS​​ervice {

/ *
私有(private)最终Map registrationUsers = new HashMap();
* /
私有(private)静态最终列表DEFAULT_AUTHORITIES = AuthorityUtils.createAuthorityList(“ROLE_USER”);
protected 静态Logger logger = Logger.getLogger(“service”);
/ **
*实现{@code AuthenticationUserDetailsS​​ervice},它可以完全访问提交的内容
* {@code Authentication}对象。由OpenIDAuthenticationProvider使用。
* /
public UserDetails loadUserDetails(OpenIDAuthenticationToken token ){
字符串ID = token.getIdentityUrl();
字符串email = null;
字符串firstName = null;
字符串lastName = null;
字符串fullName = null;
列出属性= token.getAttributes();
for(OpenIDAttribute attribute:attributes){
如果(attribute.getName()。equals(“电子邮件”)){
电子邮件= attribute.getValues()。get(0);
}
如果(attribute.getName()。equals(“firstName”)){
firstName = attribute.getValues()。get(0);
}
如果(attribute.getName()。equals(“lastName”)){
lastName = attribute.getValues()。get(0);
}
如果(attribute.getName()。equals(“全名”)){
fullName = attribute.getValues()。get(0);
}
}
如果(fullName == null){
StringBuilder fullNameBldr = new StringBuilder();
如果(firstName!= null){
fullNameBldr.append(firstName);
}
如果(lastName!= null){
fullNameBldr.append(“”).append(lastName);
}
fullName = fullNameBldr.toString();
}
CustomUserDetails用户=新的CustomUserDetails(id,fullName,email,DEFAULT_AUTHORITIES);
logger.debug(“设置用户名” +全名+“电子邮件” +电子邮件);
返回用户;
}
}

我的CustomUserDetails.java

公共(public)类CustomUserDetails扩展了用户{
私有(private)静态最终长serialVersionUID = 1L;
私有(private)字符串电子邮件;
私有(private)字符串名称;
公共(public)CustomUserDetails(字符串ID,字符串名称,字符串电子邮件,收集权限){
super (名称,“未使用”,true,true,true,true,权威);
this.email =电子邮件;
this.name =名称;
}
公共(public)字符串getEmail(){
退回电子邮件;
}

public void setEmail(String email){
this.email =电子邮件;
}
公共(public)无效setName(String name){
this.name =名称;
}

公共(public)字符串getName(){
返回名称;
}
}



...
<存储库>
org.springframework.maven.milestone
Spring Maven里程碑存储库
http://maven.springframework.org/milestone

...
<依赖性>
org.springframework.security
spring-security-core
3.1.0.RC1

<依赖性>
org.springframework.security
spring-security-web
3.1.0.RC1
jar
编译

<依赖性>
org.springframework.security
spring-security-config
3.1.0.RC1

<依赖性>
org.springframework.security
spring-security-openid
3.1.0.RC1

<依赖性>
org.springframework
spring-webmvc
3.0.5.RELEASE

<依赖性>
org.springframework.security
spring-security-openid
3.1.0.RC1
pom
编译


希望可以为您节省时间。

最佳答案

如我所见,问题文本本身包含答案。为了清楚起见,我只是将其发布并作为答案发布给其他遇到相同问题的开发人员。我花了一段时间才弄清楚那个问题的答案!

要访问用户的电子邮件和名称,您需要在安全性xml文件中添加以下配置。

<security:attribute-exchange identifier-match="https://www.google.com/.*">
    <security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" />
    <security:openid-attribute name="firstName" type="http://axschema.org/namePerson/first" required="true" />
    <security:openid-attribute name="lastName" type="http://axschema.org/namePerson/last" required="true" />
</security:attribute-exchange>
<security:attribute-exchange identifier-match=".*yahoo.com.*">
    <security:openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
    <security:openid-attribute name="fullname" type="http://axschema.org/namePerson" required="true" />
</security:attribute-exchange>

此后,可以在AuthenticationUserDetailsService类中对其进行访问,如下所示。
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) {
    String id = token.getIdentityUrl();
        :
        :
    List attributes = token.getAttributes();
    for (OpenIDAttribute attribute : attributes) {
        if (attribute.getName().equals("email")) {
            email = attribute.getValues().get(0);
        }
        if (attribute.getName().equals("firstName")) {
            firstName = attribute.getValues().get(0);
        }
        if (attribute.getName().equals("lastName")) {
            lastName = attribute.getValues().get(0);
        }
        if (attribute.getName().equals("fullname")) {
            fullName = attribute.getValues().get(0);
        }
    }
        :
        :
    // form and return user object
}

考虑到我们现在使用更多的基于Java的配置/ bean,将这些XML配置转换为基于Java的配置应该不是问题。

希望能帮助到你。

关于spring - 具有Openid和数据库集成的Spring Security,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7309133/

相关文章:

java - 请求并使用身份验证访问 token

java - 在 Web 应用程序中验证用户身份的最佳方式

security - 如何安全地存储用户的 OpenID

java - 无法执行目标 org.springframework.boot :spring-boot-maven-plugin:2. 2.5.RELEASE:run (default-cli)

java - Spring 规范和可分页

java - 当登录尝试超过 3 次时,用户无法使用 Spring Security Rest API 登录?

spring - 为什么 Spring 在 Authentication 和 UserDetails 中有重复字段?

java - 如何在 spring-security 中取消/** URL 模式

java - Jackson StdDeserializer 的自定义实例中 Autowiring Bean

java - 无法启动引用终结器线程