我對Spring和Spring Security非常陌生,希望有人能幫助我解決以下問題。Spring Security與OpenID和數據庫集成
我想要實現的是在用戶通過OpenID提供商(gmail)成功驗證後提取用戶的用戶名和電子郵件地址,然後檢查數據庫以便爲該用戶加載usermodel。
在我的彈簧security.xml文件,我有
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 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"> <security:authentication-manager alias="openIDAuthenticationManager" /> <bean id="authenticationSuccessHandler" class="org.school.openid.service.YouEatAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/krams/main/common" /> <property name="attributes2UserDetails" ref="openIDAttributes2UserDetails" /> </bean> <security:http > <security:anonymous enabled="false" /> <security:logout /> <security:openid-login user-service-ref="userDetailsServiceOpenIDImpl" authentication-success-handler-ref="authenticationSuccessHandler" login-page="/krams/auth/login" authentication-failure-url="/krams/auth/login?error=true"> <security:attribute-exchange> <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:openid-login> </security:http> <bean id="openIDAttributes2UserDetails" class="org.school.openid.service.OpenIDAttributes2UserDetailsImpl" /> <bean id="userDetailsServiceOpenIDImpl" class="org.school.openid.service.UserDetailsServiceOpenIDImpl" /> </beans>
我的問題是在UserDetailsServiceOpenIDImpl.java是
public class UserDetailsServiceOpenIDImpl implements UserDetailsService { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { System.out.println(username); //extract username and email address, HOW? } }
print語句打印出類似
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(); List attributes = token.getAttributes();
到loadUserByUsername方法。但是「令牌」對象爲空。
編輯2 通過以下https://fisheye.springsource.org/browse/spring-security/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml?hb=true頁,我能夠額外的姓名和電子郵件地址的用戶。 我的彈簧security.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 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"> <security:authentication-manager alias="openIDAuthenticationManager" /> <security:http pattern="/krams/auth/login" security="none"/> <security:http auto-config="true" access-denied-page="/krams/auth/denied"> <security:intercept-url pattern="/krams/main/*" access="ROLE_USER" /> <security:anonymous enabled="false" /> <security:logout invalidate-session="true" logout-success-url="/krams/auth/login" logout-url="/krams/auth/logout"/> <security:openid-login user-service-ref="registeringUserService" login-page="/krams/auth/login" authentication-failure-url="/krams/auth/login?error=true" default-target-url="/krams/main/common"> <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> </security:openid-login> <!-- if remember is needed <security:remember-me token-repository-ref="tokenRepo"/> --> </security:http> <bean id="tokenRepo" class="org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl" /> <!-- A custom UserDetailsService which will allow any user to authenticate and "register" their IDs in an internal map for use if they return to the site. This is the most common usage pattern for sites which use OpenID. --> <bean id="registeringUserService" class="org.school.openid.service.CustomUserDetailsService" /> </beans>
我CustomUserDetailsService.java
public class CustomUserDetailsService implements AuthenticationUserDetailsService { /* private final Map registeredUsers = new HashMap(); */ private static final List DEFAULT_AUTHORITIES = AuthorityUtils.createAuthorityList("ROLE_USER"); protected static Logger logger = Logger.getLogger("service"); /** * Implementation of {@code AuthenticationUserDetailsService} which allows full access to the submitted * {@code Authentication} object. Used by the OpenIDAuthenticationProvider. */ public UserDetails loadUserDetails(OpenIDAuthenticationToken token) { String id = token.getIdentityUrl(); String email = null; String firstName = null; String lastName = null; String fullName = null; 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); } } if (fullName == null) { StringBuilder fullNameBldr = new StringBuilder(); if (firstName != null) { fullNameBldr.append(firstName); } if (lastName != null) { fullNameBldr.append(" ").append(lastName); } fullName = fullNameBldr.toString(); } CustomUserDetails user = new CustomUserDetails(id,fullName,email, DEFAULT_AUTHORITIES); logger.debug("Set username " + fullName + " email " + email); return user; } }
我CustomUserDetails.java
public class CustomUserDetails extends User { private static final long serialVersionUID = 1L; private String email; private String name; public CustomUserDetails(String id,String name, String email,Collection authorities) { super(name, "unused", true,true,true,true,authorities); this.email = email; this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public void setName(String name) { this.name = name; } public String getName() { return name; } }
而且
... <repository> <id>org.springframework.maven.milestone</id> <name>Spring Maven Milestone Repository</name> <url>http://maven.springframework.org/milestone</url> </repository> ... <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>3.1.0.RC1</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.1.0.RC1</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.1.0.RC1</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-openid</artifactId> <version>3.1.0.RC1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-openid</artifactId> <version>3.1.0.RC1</version> <type>pom</type> <scope>compile</scope> </dependency>
希望可以爲您節省一些 時間。
如果你不介意從你的答案中解決你的問題,並在這裏發佈答案,那會很好。似乎你已經解決了你的問題,但它不是完全可見的。 – Makoto
你可能想看看Spring Social這樣的東西。我將它用於我的一個項目,整合比所有這些要簡單得多。他們的文檔足夠好,他們在github中有一些使用示例。 –
我同意,看看春天的社交。 –