Я очень новичок в Spring и Spring безопасности, и надеюсь, что кто-то может помочь мне решить следующую проблему.
То, что я хочу достичь, - это извлечь имя пользователя и адрес электронной почты после того, как этот пользователь будет успешно аутентифицирован провайдером OpenID (gmail), а затем проверьте его с базой данных, чтобы загрузить usermodel для этого пользователя.
В моем spring -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? } }
Оператор печати печатает что-то вроде
https://www.google.com/accounts/o8/id?id=AItOawlq2C3EdFAuqp-ski_xkgB8jsEKbe-mZE
Мои вопросы
(1) Как я могу извлечь имя пользователя и адрес электронной почты из возвращаемого URL-адреса (также, я даже не уверен, правильно ли вернулись имя пользователя и адрес электронной почты)?
(2) Запустив debug на Eclipse, YouEatAuthenticationSuccessHandler, похоже, не вызывается, когда возвращается URL-адрес (https://www.google.com/accounts/o8/id?id=AItOawlq2C3EdFAuqp-ski_xkgB8jsEKbe-mZE).
Спасибо.
Изменить спасибо за ссылку 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. Но объект "токена" имеет значение null.
Изменить 2 Следуя странице https://fisheye.springsource.org/browse/spring-security/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml?hb=true, я могу добавить имя и адрес электронной почты для пользователя. Мой spring -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>
My 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; } }
My 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>
Надежда может сэкономить вам некоторое время.