I'm trying to implement OpenId in Spring Security by following the tutorial here, but I can't seem to get it to work. When I test my implementation, it seems to discover the URL for the OpenId provider, but it never redirects me to the login page for that provider. Instead I get returned to my login page with my "You have entered an invalid username or password!" error.
我正在尝试在Spring Security中实现OpenId,但我似乎无法让它工作。当我测试我的实现时,它似乎发现了OpenId提供者的URL,但它从来没有将我重定向到该提供者的登录页面。相反,我返回到我的登录页面,我的“您输入了无效的用户名或密码!”错误。
Here's what my logger says when I try to login with, say, coraythan@aol.com:
当我试图登录时,我的日志记录者说,coraythan@aol.com:
[qtp760167714-19] INFO org.openid4java.discovery.Discovery - Starting discovery on URL identifier: http://aol.com/
[qtp760167714-19] WARN org.apache.http.client.protocol.ResponseProcessCookies - Cookie rejected: "[version: 0][name: JSESSIONID][value: C326ACEE663C4C976739D4E51A500DA7][domain: www.aol.com][path: /aol][expiry: null]". Illegal path attribute "/aol". Path of origin: "/"
[qtp760167714-19] WARN org.apache.http.client.protocol.ResponseProcessCookies - Cookie rejected: "[version: 0][name: JSESSIONID][value: D07CE2D83B0A58663C6EAA557FCFAD14][domain: www.aol.com][path: /aol][expiry: null]". Illegal path attribute "/aol". Path of origin: "/"
The second time I try it logs a different thing to the console:
我第二次尝试将不同的东西记录到控制台:
[qtp760167714-21] INFO org.openid4java.discovery.Discovery - Starting discovery on URL identifier: http://aol.com/
[qtp760167714-21] INFO org.openid4java.util.HttpCache - Returning cached HEAD response for http://aol.com/
[qtp760167714-21] INFO org.openid4java.util.HttpCache - Returning cached GET response for http://aol.com/
[qtp760167714-21] INFO org.openid4java.util.HttpCache - Returning cached GET response for https://api.screenname.aol.com/auth/openid/xrds
Trying it with a myOpenid account give slightly different messages:
使用myOpenid帐户尝试它会给出稍微不同的消息:
[qtp760167714-16] INFO org.openid4java.discovery.Discovery - Starting discovery on URL identifier: http://coraythan.myopenid.com/
And the second time:
第二次:
[qtp1540619773-25] INFO org.openid4java.discovery.Discovery - Starting discovery on URL identifier: http://coraythan.myopenid.com/
[qtp1540619773-25] INFO org.openid4java.util.HttpCache - Returning cached HEAD response for http://coraythan.myopenid.com/
[qtp1540619773-25] INFO org.openid4java.util.HttpCache - Returning cached GET response for http://coraythan.myopenid.com/?xrds=1
Using the "google login" option gives the same sort of issue. It looks identical to what I see from OpenId, but with google stuff instead.
使用“谷歌登录”选项提供了同样的问题。它看起来和我从OpenId中看到的一样,不过是谷歌。
Strangely, trying to login with a yahoo e-mail is even worse because throws a stack trace! The stacktrace seems to be thrown from OpenId4Java (the backing openid implementation used by Spring Security Openid).
奇怪的是,试图用雅虎的电子邮件登录更糟糕,因为抛出一个堆栈跟踪!stacktrace似乎是从OpenId4Java抛出的(Spring Security openid使用的支持openid实现)。
For a yahoo e-mail some of what the stack trace looks like is:
对于雅虎电子邮件,堆栈跟踪的一些内容如下:
[qtp665820578-23] INFO org.openid4java.discovery.Discovery - Starting discovery on URL identifier: http://yahoo.com/
2013-03-02 18:58:27.060:WARN:oejs.ServletHandler:Error for /j_spring_openid_security_check
java.lang.NoClassDefFoundError: org/cyberneko/html/HTMLTagBalancingListener
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:421)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383)
at org.openid4java.discovery.yadis.CyberNekoDOMYadisHtmlParser.parseDocument(CyberNekoDOMYadisHtmlParser.java:99)
at org.openid4java.discovery.yadis.CyberNekoDOMYadisHtmlParser.getHtmlMeta(CyberNekoDOMYadisHtmlParser.java:42)
at org.openid4java.discovery.yadis.YadisResolver.getHtmlMeta(YadisResolver.java:325)
at org.openid4java.discovery.yadis.YadisResolver.retrieveXrdsLocation(YadisResolver.java:453)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:252)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:232)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:166)
at org.openid4java.discovery.Discovery.discover(Discovery.java:147)
at org.openid4java.discovery.Discovery.discover(Discovery.java:129)
at org.openid4java.consumer.ConsumerManager.discover(ConsumerManager.java:542)
at org.springframework.security.openid.OpenID4JavaConsumer.beginConsumption(OpenID4JavaConsumer.java:103)
at org.springframework.security.openid.OpenIDAuthenticationFilter.attemptAuthentication(OpenIDAuthenticationFilter.java:123)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
[...]
Caused by:
java.lang.ClassNotFoundException: org.cyberneko.html.HTMLTagBalancingListener
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:430)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:421)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383)
at org.openid4java.discovery.yadis.CyberNekoDOMYadisHtmlParser.parseDocument(CyberNekoDOMYadisHtmlParser.java:99)
at org.openid4java.discovery.yadis.CyberNekoDOMYadisHtmlParser.getHtmlMeta(CyberNekoDOMYadisHtmlParser.java:42)
at org.openid4java.discovery.yadis.YadisResolver.getHtmlMeta(YadisResolver.java:325)
at org.openid4java.discovery.yadis.YadisResolver.retrieveXrdsLocation(YadisResolver.java:453)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:252)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:232)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:166)
at org.openid4java.discovery.Discovery.discover(Discovery.java:147)
at org.openid4java.discovery.Discovery.discover(Discovery.java:129)
at org.openid4java.consumer.ConsumerManager.discover(ConsumerManager.java:542)
at org.springframework.security.openid.OpenID4JavaConsumer.beginConsumption(OpenID4JavaConsumer.java:103)
at org.springframework.security.openid.OpenIDAuthenticationFilter.attemptAuthentication(OpenIDAuthenticationFilter.java:123)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
Here's my spring security xml:
这是我的spring安全xml:
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" access-denied-page="/accessDenied">
<!-- TODO fix all these URLs open to anyone -->
<security:intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/accessDenied" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/VAADIN/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- Admin only URLs -->
<security:intercept-url pattern="/admin/*" access="ROLE_ADMIN" />
<!-- Logged in User only URLs -->
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/endpoint/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/game/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:openid-login
login-page="/"
authentication-failure-url="/?error=true"
default-target-url="/game" />
<security:logout
invalidate-session="true"
logout-success-url="/"
logout-url="/logout" />
</security:http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider
user-service-ref="userDetailsService">
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the
database -->
<bean
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"
id="passwordEncoder" />
<!-- An in-memory list of users. No need to access an external database
layer. See Spring Security 3.1 Reference 5.2.1 In-Memory Authentication -->
<!-- john's password is admin, while jane;s password is user -->
<security:user-service id="userDetailsService">
<!-- user name is based on the returned OpenID identifier from Google -->
<security:user
name="https://www.google.com/accounts/o8/id?id=AItxxioJSDLFJLjxcksdfjOpAASDFosSSoJ0E"
password="" authorities="ROLE_USER, ROLE_ADMIN" />
</security:user-service>
I have the following servlet mapping and spring security filters in my web.xml:
我在web.xml中有以下servlet映射和spring安全过滤器:
<!-- spring gets everything else -->
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
If there's any other information I can provide, I'd be glad to! I really want to get this working, but I'm not sure what I'm doing wrong.
如果我能提供其他信息,我很乐意!我真的很想做这个工作,但我不知道我做错了什么。
Thank you!
谢谢你!
1 个解决方案
#1
1
The OpenID sample that comes with Spring Security is probably a better starting point and is customized for both Google and Yahoo.
具有Spring安全性的OpenID样例可能是一个更好的起点,它是为谷歌和Yahoo定制的。
To get it running, checkout out the source using git
要让它运行,请使用git签出源代码。
git clone git://github.com/SpringSource/spring-security.git
Then it should be as simple as installing gradle and running the following commands.
然后,它应该像安装gradle和运行以下命令一样简单。
cd spring-security
gradle build
cd samples/openid
gradle jettyRun
Pointing your browser at http://localhost:8080/openid
should then give you the OpenID selector UI to choose the provider you want to authenticate with.
将浏览器指向http://localhost:8080/openid,然后为您提供openid选择器UI,以选择要进行身份验证的提供者。
#1
1
The OpenID sample that comes with Spring Security is probably a better starting point and is customized for both Google and Yahoo.
具有Spring安全性的OpenID样例可能是一个更好的起点,它是为谷歌和Yahoo定制的。
To get it running, checkout out the source using git
要让它运行,请使用git签出源代码。
git clone git://github.com/SpringSource/spring-security.git
Then it should be as simple as installing gradle and running the following commands.
然后,它应该像安装gradle和运行以下命令一样简单。
cd spring-security
gradle build
cd samples/openid
gradle jettyRun
Pointing your browser at http://localhost:8080/openid
should then give you the OpenID selector UI to choose the provider you want to authenticate with.
将浏览器指向http://localhost:8080/openid,然后为您提供openid选择器UI,以选择要进行身份验证的提供者。