boylesoftware / tomcat-oidcauth Goto Github PK
View Code? Open in Web Editor NEWApache Tomcat 9.0 and 8.5 authenticator implementation that extends the standard form-based authenticator with support of OpenID Connect.
License: Apache License 2.0
Apache Tomcat 9.0 and 8.5 authenticator implementation that extends the standard form-based authenticator with support of OpenID Connect.
License: Apache License 2.0
Hello,
We are trying to see if we can get some specific user attributes from IDP. I am planning to add those extra attributes into additionalScopes. My question is: Are those values stored in javax.security.Subject, header, Session, etc.? Basically how to retrieve those value within application?
Thanks,
Joanna
Hi,
I need to export http_proxy, https_proxy to make the auth calls to an authentication server. Is there a way we can do this from tomcat-oidcauth?
I tried exporting the proxy at .bashrc, then setenv.sh, catalina.sh and catalina.properties. None of this worked.
Thanks
I have a working integration with Amazon Cognito as provider. Cognito includes the groups of the authenticated user in the ID token as payload attribute "cognito:groups". What is the best way to map these groups to security roles so that Tomcat's role-based authorization works as expected, including calls to methods like request.isUserInRole(String)?
My first idea has been to implement a Realm that will generate a GenericPrincipal with role names matching the Cognito groups. Unfortunately, the Realm invoked by this Valve does not have access to the information in the ID token. All it gets is the username that was extracted from the ID token.
My second idea was to have a custom Realm that uses Cognito's REST API to fetch the information for the user with the given username, and then generate a GenericPrincipal with that username and the correct roles. I don't like this for two reasons. First, the Realm has to send another request to Cognito only to fetch information that was already fetched by the Valve before when getting the ID token. Second, this solution is also very Cognito-specific. In the best case, a solution would work with other providers as well, as long as they include group/role information in the ID token.
The third idea has been to implement another Valve that is hooked into the request processing chain after the Realm has been called. It would get the Cognito groups from the ID token in the session and then "enrich" the Principal in the request with additional roles.
The last idea would be to fork this Valve and implement this logic as a feature. Something that can be configured, like a "rolesClaim" configuration property. Like with the previous idea, the tricky thing here could be to add the extra roles to the Principal returned by the Valve.
Has someone ever done one of the above, or found another solution to this problem?
I've enabled FINE logging and have noticed the following entries:
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processUnauthenticated save request in session BAA67DB64DE91B33F0C946380609B1A4
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication existing session id 446FF24228631918E82D01EDECCECDB2
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processAuthResponse authenticating user using OpenID Connect authentication response
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processAuthResponse processing authentication response from https://login.microsoftonline.com/xxxTenantIDxxx/v2.0
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.callTokenEndpoint calling token endpoint at https://login.microsoftonline.com/xxxTenantIDxxx/oauth2/v2.0/token with: grant_type=authorization_code&code=0.AQUAyPvuuos8gkORJuhr_vRs5t3a628qeFxInUcTcUFpd88FAAA.AQABAAIAAAD--DLA3VO7QrddgJg7WevrBIB9PA3VbwGo3oJpuA3LDO8wplQsQfFywOTH70Cac0XaPO8ERhahr-FZxreQiBpsP5amjNQidRSwJnp0oxYmbq-EfOIaw2JFCcWeayKFvBfrtC_RUfkEjAGMzYMUUUEQn5sMJtM7zJsJY9I6x-tr2OP2-Uguck-TQfKa9zGBePau-EW6zvxmrdXhBMilZRfRVYe-v8GeLpk4KyWkFKvD0jTTGcmZ9S4G9IpUm_GFkUjI-MjlriVlKsm9p-BpBlkcT_lFBHDxxFgpA2L8ZY2IzxqGX3RWplFYm6uU62_SiOuVy8nMz2y-Ec6aqzaGBAiI9K-X6nay7oGG_4FI2dQHmca3LOwdLqGSb0lCzAv6Lqi63lf3hMrpdCdEj3zco9LWqgUip1_atbpfbvp0iVHkYV_ycHDkSiwSt8PQWCbtGglp6cCjlDNjadduY217uS8EMSx60eBAsHjaRnCr4y7nb5saPGY9utl7hPUbk5ZNzyi6G4iU-D_acGyR3hsKtH7dsqk7FfTdyErMcIxFqCePCkXcrXNlCQ7al6p5LXgWXoDQ4u6ihcUMV8gVcr9xlDMEe6ChTCXwxlHNkSGp-P9vnJ2cjah4MuaGxz37Y9RSqoa8fZJg19SnbGykVUKCSlnYaDQ9QSYQsvTOc4LHFdfMj27YbmQYIGyX9CS4eAoubmeUkkNb7vrHGU5_tHk34DsUdIAUlM634WjHV4fIN1LGVRlyeLdrNxxQltzn67LWMzQgAA&redirect_uri=https%3A%2F%2Fserver%2FTestAuthJava%2Fj_security_check
10-May-2022 09:46:20.775 FINE [https-jsse-nio-443-exec-3] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.callTokenEndpoint received response: status: 400, date: 10 mag 2022, 09:46:18, body: {"trace_id":"b2b53948-a021-4657-b714-7d8f76642200","error_description":"AADSTS900144: The request body must contain the following parameter: 'client_id'.\r\nTrace ID: b2b53948-a021-4657-b714-7d8f76642200\r\nCorrelation ID: baba76a4-1351-40c3-925a-20754cf0f6d1\r\nTimestamp: 2022-05-10 07:46:18Z","correlation_id":"baba76a4-1351-40c3-925a-20754cf0f6d1","error_codes":[900144],"error":"invalid_request","error_uri":"https://login.microsoftonline.com/error?code=900144","timestamp":"2022-05-10 07:46:18Z"}
10-May-2022 09:46:20.776 FINE [https-jsse-nio-443-exec-3] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processAuthResponse token error response: invalid_request
This is my configuration Valve
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat90.OpenIDConnectAuthenticator" providers="[{name: 'TestAuthJava', issuer: https://login.microsoftonline.com/xxTenantIDxxx/v2.0, clientId: xxxxxxx-xxxxxx-xxxxx, configUrl: https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration, tokenEndpointAuthMethod: none}]" noForm="false" />
Thanks
Folks,
Tested with Sample app, the authentication didn't happen. All I could see was Authentication Error..something went wrong with authentication.
Do we have any specific pre-reqs to work with AWS Cognito ?
Regards
Roger
In the setup we are validating against (Oracle based) we are required to make a couple of changes:
If anyone could point me to where I can add the header in the code, I'm happy to customise it myself.
Thanks in advance.
Z.
I am trying to incorporate this OIDC library to my JSF app, but I am failing to translate this code:
<c:redirect url="${requestScope['org.bsworks.oidc.authEndpoints'][0].url}"/>
In JSF such redirection is done usually in controller (bean), but I can't see this property in any object there.
For redirection to the login page usually filters are suggested, but I am failing to combine this approach with this library.
https://stackoverflow.com/questions/8480100/how-implement-a-login-filter-in-jsf
In sum, I would be grateful for any basic JSF sample app. At least to see if this library can be used here.
E.g. extend this simple app https://www.javatpoint.com/jsf-example
Thanks for creating this nice project. It seems to be quite useful for using OIDC in classic JEE applications. I'm evaluating it for one of my webapps that uses form based authentication.
I'm trying to get the sample application working with Azure AD.
I create an azure App registration where I got a clientId and a client secret. I also used a redirect URL to http://localhost:8080
When clicking on the oidc link in the sample application, I get redirected to the Azure login. After entering the credentials, the following error is displayed in the browser:
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application:
I didn't see anything in the documentation about configuring a redirect URL. Any idea what might be going wrong?
Hi all, my application is setup to work with my companies OIDC provider, however this particular provider has been having several unplanned outages in recent months which bring down my application given my Tomcat's usage of this plugin. My Tomcat configuration has multiple ways to log in, in addition to using my OIDC provider + tomcat-oidcauth.
Is there a way I can configure my provider in tomcat-oidcauth such that my application can start, regardless of if a provider is available?
Sample error:
org.apache.catalina.LifecycleException: OpenIDConnectAuthenticator could not load OpenID Connect Provider configuration.
at org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.startInternal(BaseOpenIDConnectAuthenticator.java:815)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:176)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5056)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3754)
at org.apache.catalina.manager.ManagerServlet.reload(ManagerServlet.java:1124)
at org.apache.catalina.manager.HTMLManagerServlet.reload(HTMLManagerServlet.java:641)
at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:217)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:211)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:666)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:291)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:820)
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:127)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at com.ibm.jsse2.b.a(b.java:123)
at com.ibm.jsse2.b.a(b.java:269)
at com.ibm.jsse2.av.a(av.java:12)
at com.ibm.jsse2.av.a(av.java:513)
at com.ibm.jsse2.f.read(f.java:9)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:257)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:297)
at java.io.BufferedInputStream.read(BufferedInputStream.java:356)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:766)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:709)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1605)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1510)
at com.ibm.net.ssl.www2.protocol.https.b.getInputStream(b.java:19)
at org.bsworks.catalina.authenticator.oidc.ConfigProvider.loadDocument(ConfigProvider.java:138)
at org.bsworks.catalina.authenticator.oidc.ConfigProvider.get(ConfigProvider.java:106)
at org.bsworks.catalina.authenticator.oidc.OPConfigurationsProvider.getOPConfiguration(OPConfigurationsProvider.java:72)
at org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.startInternal(BaseOpenIDConnectAuthenticator.java:813)
... 40 more
Much thanks,
Avery
Hi,
There is a typo in the property name "jwkstHttpReadTimeout" in OPDescriptor.java, line 238:
"jwkstHttpReadTimeout"
should be "jwksHttpReadTimeout"
, without the "t" at position 5.
Regards,
Ste
The .jsp correctly forwards the request to the issuer URL. The user can then be authenticated. After being authenticated the response contains the following: https://<system_here>:8443/base/j_security_check?code=<code_here>&scope=openid%20profile%20role&state=<state_here>&session_state=<session_state_here>. This causes Tomcat to then again send a request to the issuer with the following: http://<system_here>:3702/connect/authorize?scope=openid+profile+role&response_type=code&client_id=<client_id_here>&redirect_uri=https://<system_here>:8443/base/j_security_check&state=<state_here>.
This application also has basic local Tomcat form authentication configured in the same login.jsp. After turning on debug, the local login module is being called after each response from the issuer.
Is this related to: #25?
context.xml:
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat85.OpenIDConnectAuthenticator"
providers="[
{
name: 'theName',
issuer: 'theIssuerUrl',
clientId: 'theClientId',
clientSecret: 'theClientSecret,
additionalScopes: 'profile role'
}
]"
/>
Tomcat Version 8.5.50
Jar 2.3.0 built on 2020-02-03 14:36.
https://boylesoftware.com/maven/repo-os/org/bsworks/catalina/authenticator/oidc/tomcat-oidcauth/2.3.0/tomcat-oidcauth-2.3.0-tomcat85.jar
Thank You!
Hello,
First of all i would like to thank you for your library.
In my project i have developed a Tomcat 8.5 authentication valve that extends the main valve OpenIDConnectAuthenticator, in the valve classe i am overriding the method processAuthResponse everything works fine with the version 2.2.3. Recently we have decided to upgrade to Tomcat 8.5.57 and fourntly i have found that you already fix the compatibility issues in the 2.3.0 version but as the return type to the method processAuthResponse has been changed to the inner private type AuthedUser i can not override the method as this type is not visible in my extending class.
Could you please change the visibilté of the inner class AuthedUser so we can override the method processAuthResponse .
Thank you for your time and your great work.
Best regards,
Houssem
Hi and first of all let me say that I'm new to this topic.
I'm in a situation where I can't change the login page of my Web Application (can't change the source code) and I would like to understand if it is possible to force immediately the redirect for not authenticated request to the OP Hosted UI.
I can act just on my tomcat configurations
Of course, this is not an issue but just a request.
I wrote a stub realm as you suggested, but the realm always returns with username as null. I have used usernameClaim="email". So the email should be available to the realm.
This isnt happening:
Once the authenticator exchanges the authoization code for the ID Token, it extracts a field from the token (a claim) used as the username in the Tomcat's Realm and looks up the user.
This is my realm code
`
package com.tfsc.mirror.realm;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
public class MirrorRealm extends RealmBase {
private final Log log = LogFactory.getLog(this.getClass());
private String username;
private String password;
@Override
protected String getName() {
return this.username;
}
@Override
protected String getPassword(String s) {
return this.password;
}
@Override
public Principal authenticate(String username, String credentials) {
this.username = username;
this.password = credentials;
/* authentication just check the username and password is same*/
log.info("Authentication is taking place with userid: "+username);
return getPrincipal(username);
}
@Override
protected Principal getPrincipal(String string) {
List<String> roles = new ArrayList<String>();
roles.add("user"); // Adding role "user" role to the user
log.info("username is "+ this.username);
log.info("Realm: "+this);
Principal principal = new GenericPrincipal(this.username, this.password,roles);
//Principal principal = new GenericPrincipal("test", "test",roles);
log.info("Principal: "+principal);
return principal;
}
}
`
My configuration is:
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat85.OpenIDConnectAuthenticator"
providers="[
{
name: 'OKTA',
issuer: https://somedomain.com/oauth2/something,
configurationDocumentUrl: https://somedomain.com/oauth2/something/.well-known/oauth-authorization-server,
clientId: ,
clientSecret:
}
]"
usernameClaim="email" additionalScopes="email" noForm="true"/>
Hi,
I have set up tomcat-oidcauth v2.2.5 on Tomcat 8.5.33. I have configured 2 providers for authentication - Google and Microsoft. The Google authenticator works as expected - the user clicks a link on our login page, they are redirected to a Google sign in page, they enter their details and if a corresponding user exists for them in our database, they are logged in.
With Microsoft, we are redirected to the page as expected, and when we enter our details we are redirected to the error-login page. The URIs and Client Secrets match for the application in Azure AD, and the org.bsworks.oidc.error request attribute is null.
Is there some extra configuration required for Microsoft Authentication? I have logging in my tomcat instance set to FINE, but I'm not seeing any logging relating to org.bsworks.
Thank you!
Hi there,
during the configuration using jwks
the module expects the kid
parameter.
Unfortunately our jwks setup does not return a kid
parameter:
https://login.helmholtz-data-federation.de/oauth2/jwk
Is there a workaround for this?
Error message of tomcat is:
[..]
Caused by: java.lang.IllegalArgumentException: JSONObject["kid"] not found.
at org.bsworks.util.json.JSONObject.get(JSONObject.java:381)
at org.bsworks.util.json.JSONObject.getString(JSONObject.java:582)
at org.bsworks.catalina.authenticator.oidc.JWKSet.<init>(JWKSet.java:56)
at org.bsworks.catalina.authenticator.oidc.OPConfiguration$1.parseDocument(OPConfiguration.java:63)
at org.bsworks.catalina.authenticator.oidc.OPConfiguration$1.parseDocument(OPCon
[..]
This is my context.xml
`<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat85.OpenIDConnectAuthenticator"
providers="[
{
name: 'OKTA',
issuer: https://okta-domain.com/oauth2/default,
configurationDocumentUrl: https://okta-domain.com/oauth2/default/.well-known/oauth-authorization-server,
clientId: ,
clientSecret:
},
]"
usernameClaim="email" additionalScopes="email" noForm="true"/>`
I am getting a 401 response. This is the exact response.
FINE [https-openssl-nio-8443-exec-4] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.callTokenEndpoint received response: status: 401, date: 4 Jun, 2018 10:55:29 AM, body: {"error_description":"Cannot supply multiple client credentials. Use one of the following: credentials in the Authorization header, credentials in the post body, or a client_assertion in the post body.","error":"invalid_request"}
I tried removing the client secret but that too came back with client not recognised
06-Jun-2018 16:03:17.655 FINE [https-openssl-nio-8443-exec-8] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processAuthResponse failed to authenticate the user in the realm
I am not sure if this can be categorised as a bug. I have read this:
Once the authenticator exchanges the authoization code for the ID Token, it extracts a field from the token (a claim) used as the username in the Tomcat's Realm and looks up the user. If the user is found in the realm, the user becomes the authenticated user and the HTTP session becomes authenticated.
Do we have to provide the claim/username in the memory realm?
For example:
<role rolename="user"/> <user username="[email protected]" password="" roles="user"/>
This works fine.
It would be difficult to scale by adding users like this in the MemoryRealm. I have no DB of users/passwords so I cant use JDBC/DataSourceRealm.
Will the authenticator look up the user from the JNDI realm? Is there a specific configuration to let the authenticator look up a user in the JNDI realm (LDAP)? I have LDAP set up in other environments.
I was of the understanding that when the authenticator exchanges the authorization code for the ID token, the whole process would end there.
Upgrading to tomcat 8.5.50, the valve stop working, instead of giving access to the application, the valve is redirecting to form.
I tried to debug the cause, I do not understand why yet, but I notice the difference between previous tomcat version.
Prior to 8.5.50, after a successfull authentication the org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication(Request, HttpServletResponse) method was redirecting to the original URI, then
performAuthentication is called again and following code was returning true
// check if resubmit after successful authentication
if (this.matchRequest(request))
return this.processResubmit(request, response);
in tomcat 8.5.50, matchRequest is returning false for some reasons so the valve is redirecting to form instead of the application
Hi,
is it possible to extract user name from access token istead of ID token?
Hi,
I'm wondering how to logout the authenticated user. I tried request.logout();
but it has no effect.
Any idea how to do it?
Thanks
Hi. I'm getting an error on login when the web.xml contains the distributable tag.
The class Authorization is being set as an attribute on the session, but is not marked as Serializable.
java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute [org.bsworks.oidc.authorization]
org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1411)
org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1367)
org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:137)
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processAuthResponse(BaseOpenIDConnectAuthenticator.java:1495)
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication(BaseOpenIDConnectAuthenticator.java:924)
org.bsworks.catalina.authenticator.oidc.tomcat90.OpenIDConnectAuthenticator.doAuthenticate(OpenIDConnectAuthenticator.java:41)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:631)
Version 2.2.2
I have been testing your sample application for this plugin with JWS 3.0 with bundled Tomcat 8.0 (using the 8.0 jar). I encounter the failure "java.lang.NoSuchMethodError org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.checkForCachedAuthentication" when attempting to access a secure page.
I downloaded standalone Tomcat 8.5 and the plugin works fine with the same sample application configuration (using the 8.5 jar)
I've downloaded standalone Tomcat 8.0 and it is working fine, so the issue appears isolated to the JWS 3.0 Tomcat 8.0 version.
Can you address the incompatibility the JWS 3.0 bundled Tomcat 8.0 version to allow it to function?
Error in browser when attempting to access the secure page-a link in the sample app:
HTTP Status 500 - org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.checkForCachedAuthentication(Lorg/apache/catalina/connector/Request;Ljavax/servlet/http/HttpServletResponse;Z)Z
type Exception reportmessage org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.checkForCachedAuthentication(Lorg/apache/catalina/connector/Request;Ljavax/servlet/http/HttpServletResponse;Z)Z
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.NoSuchMethodError: org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.checkForCachedAuthentication(Lorg/apache/catalina/connector/Request;Ljavax/servlet/http/HttpServletResponse;Z)Z
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication(BaseOpenIDConnectAuthenticator.java:807)
org.bsworks.catalina.authenticator.oidc.tomcat80.OpenIDConnectAuthenticator.authenticate(OpenIDConnectAuthenticator.java:27)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:576)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1103)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:285)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2419)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2408)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.18 logs.Apache Tomcat/8.0.18
I am trying to get your org.bsworks.catalina.authenticator.oidc package to work without much luck. I have Ubuntu 16.04, Tomcat 8.5.6, java-7-openjdk-amd64. I am using version 1.01 of your package.
In conf/context.xml:
<Valve className="org.bsworks.catalina.authenticator.oidc.OpenIDConnectAuthenticator"
discoveryDocumentURL="https://accounts.google.com/.well-known/openid-configuration"
clientId="XXX.apps.googleusercontent.com"
clientSecret="XXX"
hostedDomain="example.com"
usernameClaim="email"/>
I have the webapp web.xml configured for FORM authentication, and a JDBCRealm set up for my Postgresql database. When I point my browser at the server, it goes straight to my login.html page, and I can authenticate using the FormAuthenticator. Looking at catalina.out (having set logging to FINE), I see:
15-Nov-2016 08:48:37.507 FINE [localhost-startStop-1] org.bsworks.catalina.authenticator.oidc.OpenIDConnectAuthenticator.httpGet getting data from https://accounts.google.com/.well-known/openid-configuration
15-Nov-2016 08:48:39.606 FINE [localhost-startStop-1] org.bsworks.catalina.authenticator.oidc.OpenIDConnectAuthenticator.httpGet received response: {
"issuer": "https://accounts.google.com", ...
but no other messages from org.bsworks.catalina.authenticator.oidc.OpenIDConnectAuthenticator. I even added a statement to the source to log "Alive" on entry to authenticate. This produces no output. I'm not understanding why startInternal() is getting called, but authenticate is not.
Note, updating to 8.5.x requires adding this dependency:
<!-- https://mvnrepository.com/artifact/javax.security.auth.message/javax.security.auth.message-api -->
<dependency>
<groupId>javax.security.auth.message</groupId>
<artifactId>javax.security.auth.message-api</artifactId>
<version>1.1</version>
</dependency>
Thanks,
Jeff E Mandel MD MS
I tried with sample application and I am getting the Authentication error .
Error Message:
Authentication Error
Something went wrong with the authentication. Check the authenticator debug log for details.
Go Back Home
URL: https://mypc.abc.com:8443/demo/j_security_check?code=AQABAAIAAACQN9
Logs:
20-Oct-2019 11:47:11.682 FINE [https-openssl-nio-8443-exec-8] org.apache.catalina.authenticator.AuthenticatorBase.invoke Failed authenticate() test
another Query:
In Azure portal if I configure https://mypc.abc.com:8443/demo/j_security_check then only the authentication is taking place. Do we really need to add j_security_check for authentication?
-Mallikarjun
I am not being redirected to the secure page after successful authentication, the login page still persists.
Here are my logs:
22-May-2020 13:43:54.200 FINE [https-jsse-nio-8443-exec-4] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication authentication of "[email protected]" was successful
22-May-2020 13:43:54.200 FINE [https-jsse-nio-8443-exec-4] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication redirecting to original URI: /tomcat8_oidcauth_sample_war/secure/page-a
22-May-2020 13:43:54.203 FINE [https-jsse-nio-8443-exec-5] org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.processUnauthenticated save request in session BLAHBLAHBLAHBLAH
I am trying to implement this solution using Microsoft Azure AD.
I have been grappling at this issue for some days now. I managed to setup the sample application on my local environment and run the application on Intelli-J in debug mode. The application managed to direct me to my OP's login page where i logged in. After the authenticator return with a code as per the below link,
the authenticator redirected me to the error page with no visible errors. I checked all my tomcat logs and i found absolutely nothing. i set all my log levels to ALL and there was still no error printed.
Is there another we for me to debug this issue besides the logs?
Your assistance would be highly appreciated.
for the testing purpose in the local machine, this implementation fails to extend its support to HTTP redirects.
Hi there.
I've been hunting down an OpenID issue in our company's product - setting the JSESSIONID
cookie SameSite policy to 'strict' prevents the OpenID connect flow from working - the Authorization Endpoint responds, but the cookie is filtered from the response, and Tomcat doesn't find the existing session. That's pretty much as expected, but it causes the following code in BaseOpenIDConnectAuthenticator.performAuthentication
to get a null for the session request, and so to provide a misleading log message and an 'instant' 408 Timeout response. Would it be worth adjusting the log message to eg. "could not retrieve session information: either user took so long to log on that the session expired, or Tomcat could not retrieve session details"? Could maybe help someone else having the same issue.
Cheers.
final Session session = request.getSessionInternal(false);
if (session == null) {
// log using container log (why container?)
this.log.debug("user took so long to log on the session expired");
In previous version of OpenID connector (the OpenID 2.0 connector)
It was possible to combine Open ID and Form authentication (see Login page part of https://www.boylesoftware.com/wiki/index.php/OpenID_Authenticator_for_Tomcat)
According to documentation It seems, with OpenID connect connector, it is not possible anymore, am I right ?
Hi,
Is this plug-in supports only auth code grant type ? or supports all types of grant types ?
Kind Regards,
Raghu
We noticed that Microsoft occasional will create a secret key with a plus sign in (+).
This causes the oauth process to fail with a key error. If we URL encode the key in the valve config this solves the problem however we are persisting an encoded secret rather than the actual secret which can be confusing.
Should the key secret be encoded before its sent to the Auth Provider?
We try to setup tomcat-oidcauth (2.2.5 or 2.3.0) to also work with CORS:
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat90.OpenIDConnectAuthenticator"
allowCorsPreflight="always"
providers="[
{
name: *****,
issuer: ****************,
clientId: *****************************,
clientSecret: *************************
}
]"
/>
When we send an OPTION Request to a page that is authenticated by oidcauth, tomcat creates a new session cookie and redirects to the openid login host. However tomcat reacts correct when we send an OPTIONS request to any page that is not under control of oidcauth.
Here is a snippet from the logfile that demonstrates OPTIONS requests are treated as regular requests:
05-Mar-2020 14:23:10.401 FINE [http-nio-8487-exec-26] org.apache.catalina.authenticator.FormAuthenticator.forwardToLoginPage Forwarding request for [/******/x.jsp] made with method [OPTIONS] to login page [/*******] of context [/****] using request method GET
A quick search within the connector sources lets us believe that OPTIONS requests are not recognized and handled as normal requests without sessionid. However its possible that our configuration is wrong.
Any advice?
kind regards,
Hussayn
In tomcat 8.5.46, they change behavior of Base64 utility, it is not longer "url safe"
so OIDC valve is failing with
java.security.SignatureException: Signature length not correct: got 243 but was expecting 252
at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:189)
at java.security.Signature$Delegate.engineVerify(Signature.java:1222)
at java.security.Signature.verify(Signature.java:655)
Because of
final byte[] idTokenSignature = Base64.decodeBase64(idTokenParts[2]);
that is not handling signature with '-' and '_' as it was before.
They will restore "url safe" decode method in 8.5.47 but with another signature:
org.apache.tomcat.util.codec.binary.Base64.decodeBase64URLSafe(String)
But changing that would break the ability of using the valve with older version of tomcat.
Maybe code should be change, to use java.util.Base64.getUrlDecoder().decode(str), so it will work on every version of tomcat
I try to use openid connect with Tomcat 9.0.
I send a request like this
https://federate.abcd.com/as/authorization.oauth2?client_id=aaa&redirect_uri=http://localhost:20000/Callback&response_type=code&scope=openid%20email%20profile&state=abc
After login, it will redirect back to
http://localhost:20000/Callback?code=Mqwo3SSfAAp6uFfOViUfIxxxxxxxxxxxxxxxxxx&state=abc
However, what next?
I do not understand how to decode the "code"?
how to write the callback?
how to get the email from code?
The example Valve configuration in README.md is not up-to-date. It features properties like "logoutUrl" or "postLogoutPage" which are never used in the source code.
Search for "logoutUrl":
https://github.com/boylesoftware/tomcat-oidcauth/search?q=logoutUrl
-> Only found in README.md.
Search for "postLogoutPage":
https://github.com/boylesoftware/tomcat-oidcauth/search?q=postLogoutPage
-> Only found in README.md.
Hello,
I hope you are doing well.
We are facing another overriding issue, as we are trying to override the isSignatureValid method to block unknown algorithms (now the returned value is true), so as the class OPDescriptor not visible we can't override this method. Can you please change the class visibility so we can fix this issue.
Thank you for your help and time.
Best regards,
Houssem
When using email as usernameClaim, at least Azure AD seems to have different styles for email addresses. Some people have [email protected] and other ones have [email protected]. As tomcat handles username in case-sensitive manner, this causes easily situations where user is not found after successful authentication (just because of different way of typing upper/lowercase characters).
Would it be possible to have a parameter to Valve that would downshift usernames (for example) before passing them to tomcat ?
Hello,
On ADFS 2016 it is possible to configure some custom claims with OpenID Connect sign-in,
but it is necessary to send a custom scope.
On https://github.com/boylesoftware/tomcat8-oidcauth/blob/master/src/main/java/org/bsworks/catalina/authenticator/oidc/OpenIDConnectAuthenticator.java line 518, scope is hardcoded.
would it be possible to add a configuration for this (as userNameClaim) ?
I can do a pull request if you want
Using v2.5. I am seeing this warning when a user is authenticated:
WARNING [https-jsse-nio-9443-exec-6] org.apache.catalina.session.ManagerBase.willAttributeDistribute Skipped session attribute named [org.bsworks.oidc.authorization] because the value type [org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator$Authorization] did not match the filter [java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.realm\.GenericPrincipal\$SerializablePrincipal|\[Ljava.lang.String;]
I am having trouble successfully authenticating users on my server. I've enabled FINE logging and have noticed the following entries:
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication authentication of "" was successful
org.bsworks.catalina.authenticator.oidc.BaseOpenIDConnectAuthenticator.performAuthentication redirecting to original URI: /
org.apache.catalina.authenticator.AuthenticatorBase.invoke Failed authenticate() test
By my interpretation this is telling me that I'm authenticating using tomcat-oidcauth, but then failing the default authenticator. Is this correct? If so, are there any suggestions on how to debug this issue on my end?
Hi,
I'm using the tomcat-oidcauth-2.3.0-tomcat85.jar and some static html for a basic Tomcat 8.5 dummy test setup. I've gotten close to configuring things correctly, however after authenticating at my Identity Providers page, I'm redirected back to my form-error-page but without request headers to indicate the cause of the error.
With my current understanding and by following the Operation Details and The Login Error Page, I should be seeing an error listed in under the name org.bsworks.oidc.error
.
As an example, I follow these steps:
In Google Chrome's Developer tools, I can view the page I'm redirected back to with a few parameters in the URL:
https://localhost:8443/test/j_security_check?code=xxxx&grant_id=xxxx&state=xxxx
and while looking at the headers supplied, I do not see any under the Request Headers
portion beginning with org.bsworks.oidc.*
Does this appear to be an issue with bsworks not providing an error in the request headers, a flow issue, or something else?
Thanks!
-Avery
Hi,
Thanks for the great connector.
I had a couple of questions as below:
Is there a way to specify valve setting in context per web app level ? (currently I am specifying the valve in the tomcat level -context.xml file)
What is the security implication of having the client secret in plain view inside context.xml file on the server? are there ways to hash/hide it further?
The final step in the authentication workflow of looking up of the user id in the tomcat Realms, what is the purpose of doing it ? can roles be also communicated by the IDP, can we disable this lookup?
Thanks
Hello,
I see there is a branch where changes has been made to make the connector compatible to tomcat 85,
is there any jar available from maven ?
I have installed your sample oidcauth, but got an authentication error after IDP authenticated my login account. Where is the authenticator debug log located?
Error message:
Authentication Error
Something went wrong with the authentication. Check the authenticator debug log for details.
Go Back Home
Any plans to add the access token to the header. This could be useful for applications as they move to use OIDC and leverage access token for access.
What is the plan for Tomcat 9.x compatibility? I haven't tried it yet, but assume that some change might be necessary for the next version just as Tomcat 8.0 and 8.5 had some differences.
I there,
I am having problems connecting to our OpenID Connect service. The server rejects the request with an 406 HTTP error:
...
by: java.io.IOException: Server returned HTTP response code: 406 for URL: https://login.helmholtz-data-federation.de/oauth2/jwk
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
....
I tried curling the server, and it works fine:
$ curl -k https://login.helmholtz-data-federation.de/oauth2/jwk
{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","n":"<content-erased>"}]}
The context.xml
is like this:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/app">
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat85.OpenIDConnectAuthenticator"
providers="[
{
name: hdfAAI,
issuer: https://login.helmholtz-data-federation.de,
configurationDocumentUrl: https://login.helmholtz-data-federation.de/oauth2/.well-known/openid-configuration,
clientId: <xxx>,
clientSecret: <xxx>,
}
]"
usernameClaim="email" additionalScopes="email" />
</Context>
Any suggestions on why this fails?
I am using Tomcat 9.0 at 64 Bit window 7. I try to let my Tomcat to connect to Google Account by OpenID connect. However, it does not work. Can anyone help me?
My setting:
content.xml
<Valve className="org.bsworks.catalina.authenticator.oidc.tomcat90.OpenIDConnectAuthenticator"
providers="[
{
name: Google,
issuer: https://accounts.google.com,
clientId: xxxxxxxxxxxxxxxxxxxxxxx,
clientSecret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
extraAuthEndpointParams: {
hd: abc.com
}
}
]"
/>
at web.xml
add this
JSP Code
/OIDC/login.jsp
/OIDC/login-error.jsp
then restart the tomcat
Then, at UI
http://localhost/OIDC/login.jsp
I press username and password for a google account. Then, it will forward to http://localhost/OIDC/j_security_check.
So, it is means not work?????? Am I do it wrongly?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.