Handing Remote-User variable with Shibboleth Service Provider - perl

Perl CGI web application is my Shibboleth Service Provider.
The cgi protected by Shibb is causing the redirect to Shibboleth IDP.
Authentication successful at the IDP and redirect back to the protected CGI page.
I can see Shibboleth Session variables, but i don't see 'REMOTE_USER' variable set.
Shibboleth2.xml has 'REMOTE-USER="eppn transient-id targeted-id".
What am i doing wrong?? What do i need to do in the attribute configuration files to set the REMOTE_USER(REMOTE-USER) ?
thanks

Do you have settings in your attribute-map.xml that will create one of eppn, transient-id, targeted-id? I added persistent-id to the aliases as follows:
<!-- more OLAT support -->
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"
id="Shib-eduPersonTargetedID"
aliases="Shib-SwissEP-UniqueID persistent-id">
<AttributeDecoder xsi:type="NameIDAttributeDecoder"
formatter="$Name!!$NameQualifier!!$SPNameQualifier"/>
</Attribute>
and promptly, that value showed up in REMOTE_USER as well.

Related

Elytron programmatic login with FORM authentication

we are currently migrating from legacy security subsystem to Elytron and have a Struts2 based web application deployed in JBoss EAP 7.3.6 which should support multiple "flavors" of authentication.
The standard way of logging in should be that a user manually provides credentials in a login form (j_security_check) and clicks the corresponding button. This works well with Elytron in our setup.
The second possibility is, that the GET request to protected content of the web application can contain a custom cookie that contains a JWT token. This cookie is intercepted by a io.undertow.server.HttpHandler which deals with the incoming request in its io.undertow.server.HttpHandler#handleRequest method. This handler is registered by io.undertow.servlet.api.DeploymentInfo#addSecurityWrapper with a DeploymentInfo which is provided by an implementation of io.undertow.servlet.ServletExtension. The ServletExtension is registered as a service provider in META-INF/services/io.undertow.servlet.ServletExtension.
The request handling in our implementation of io.undertow.server.HttpHandler#handleRequest extracts the JWT token from the cookie, pre-validates it and determines the contained username. This username and the token as a password are used as inputs for a call to javax.servlet.http.HttpServletRequest#login.
With the legacy security subsystem, the behavior of the server was, that this call to login triggered the authentication against the configured legacy security domain AND created a session in Undertow so that the HTTP 200 response for the previous GET request contained a Set-Cookie header with a fresh JSESSIONID cookie.
With Elytron, javax.servlet.http.HttpServletRequest#login doesn't do anything, neither an authentication against an Elytron security domain and security realm nor the creation of a session is triggered. The browser simply shows the login form which should get skipped by the described interception process.
I debugged the implementation of javax.servlet.http.HttpServletRequest#login that comes with JBoss. We start in io.undertow.servlet.spec.HttpServletRequestImpl#login which calls login = sc.login(username, password). This SecurityContext, when using Elytron, is org.wildfly.elytron.web.undertow.server.SecurityContextImpl. org.wildfly.elytron.web.undertow.server.SecurityContextImpl#login first checks if (httpAuthenticator == null). The httpAuthenticator is only set in org.wildfly.elytron.web.undertow.server.SecurityContextImpl#authenticate which gets called by a call to javax.servlet.http.HttpServletRequest#authenticate.
This explains, why a plain call to io.undertow.servlet.spec.HttpServletRequestImpl#login was doing nothing. I tried to call javax.servlet.http.HttpServletRequest#authenticate first, to instantiate that httpAuthenticator internally, and then javax.servlet.http.HttpServletRequest#login. This at least finally triggered the authentication and authorization against the configured Elytron security domain and security realm. Authentication/authorization were successful but Undertow still didn't issue a new JSESSIONID cookie and the browser again showed the login form instead of proceeding to the protected resources.
I'm currently out of ideas, how to proceed with this issue und how to achieve the same behavior as with the legacy security subsystem. Why does the Elytron implementation of io.undertow.security.api.SecurityContext behave so differently compared to the one for legacy security (io.undertow.security.impl.SecurityContextImpl)? How am I supposed to log in programatically in a FORM based web application using Elytron with javax.servlet.http.HttpServletRequest#login and/or javax.servlet.http.HttpServletRequest#authenticate?
The relevant JBoss configuration for all this looks like this:
Undertow:
<application-security-domains>
<application-security-domain name="my_app_security_domain" http-authentication-factory="MyHttpAuthFactory"/>
</application-security-domains>
Elytron:
<security-domains>
<security-domain name="MySecurityDomain" default-realm="MyCachingRealm" permission-mapper="default-permission-mapper">
<realm name="MyCachingRealm" role-decoder="FromRolesAttributeDecoder"/>
</security-domain>
</security-domains>
<security-realms>
<custom-realm name="MyCustomRealm" module="module name redacted" class-name="class name redacted"/>
<caching-realm name="MyCachingRealm" realm="MyCustomRealm" maximum-age="300000"/>
<identity-realm name="local" identity="$local"/>
</security-realms>
<mappers>
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
<permission-mapping>
<principal name="anonymous"/>
<permission-set name="default-permissions"/>
</permission-mapping>
<permission-mapping match-all="true">
<permission-set name="login-permission"/>
<permission-set name="default-permissions"/>
</permission-mapping>
</simple-permission-mapper>
<constant-realm-mapper name="local" realm-name="local"/>
<constant-realm-mapper name="MyRealmMapper" realm-name="MyCachingRealm"/>
<simple-role-decoder name="FromRolesAttributeDecoder" attribute="Roles"/>
</mappers>
<http>
<http-authentication-factory name="MyHttpAuthFactory" security-domain="MySecurityDomain" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="FORM" realm-mapper="MyRealmMapper">
<mechanism-realm realm-name="MyRealm"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
<provider-http-server-mechanism-factory name="global"/>
</http>
This was a bug in JBoss EAP which has been fixed in EAP 7.3.8 and 7.4.1. See https://issues.redhat.com/browse/JBEAP-21737 and https://issues.redhat.com/browse/JBEAP-21738 for details.

OKTA(IdP) - Shibboleth(SP) with reverse proxy to Tomcat

I am spinning a big wheel now. please shed some light.
Reverse proxy is working with Apache. So, when I access https://hostname/app/default.html, it opens Tomcat app url. No issue.
The tomcat app currently redirects to https://hostname/app/login.html which has a login box.
1) Do I need to disable UserDatabase on Tomcat server.xml ?
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
2) Is this Shibboleth configuration correct ?
But, when I try configure this with OKTA- Shibboleth(3.0), it's looping OKTA SSO url.
In shibboleth2.xml
<ApplicationDefaults id="default"
entityID="https://hostname/shibboleth-sp"
REMOTE_USER="userid" >
<SSO entityID="http://www.okta.com/~~~~">
OKTA's metadata is downloaded and located with shibboleth2.xml file.
cert is also generated and placed in the same folder.
3) Is this OKTA configuration correct ?
In OKTA widget configuration menu,
- Single sign on url :https://hostname/Shibboleth.sso/SAML2/POST
- recipient url : https://hostname/Shibboleth.sso/SAML2/POST
- destination url :https://hostname/Shibboleth.sso/SAML2/POST
- audience restriction :https://hostname/shibboleth-sp <-- above SP entityID
- default relay state : ??
right now, when I click on the widget on OKTA, it's looping.
https://hostname/Shibboleth.sso/SAML2/POST
contains SAML response.
then, it redirects to OKTA SSO url. It never ends.
https:// xxx.oktapreview.com/app/xx_reverse_proxy_/xxxx/sso/saml?SAMLRequest=~~~&RelayState=~~~
This contains SAML request but it looks like this.
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="https://hostname/Shibboleth.sso/SAML2/POST"
Destination="https://okta sso/sso/saml"
ID="xx"
IssueInstant="2018-11-02T15:39:24Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml:Issuer
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://hostname/shibboleth-sp
</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="1"/>
Is this Issuer url correct? Why is it looping and how to fix ?
Re Q#1: You only need Tomcat users if you're going to protect an application with it, such as the Tomcat manager. Otherwise, no.
Re Q#2: You list <SSO entityID="http://www.okta.com/~~~~"> but Destination="https://okta sso/sso/saml" from the SAML. You might want to check http/https. This is a very common cause of looping. Eliminate any potential http/https inconsistency.
FWIW Issuer looks correct to me... that's what you specify in entityID="https://hostname/shibboleth-sp"

How to correctly configure SAML 2.0 SP

I have an Identity Provider that I wish to preform SSO against using SAML 2.0
I'm using https://github.com/KentorIT/authservices
The IdP configuration is :
Entity Id: https://xxx.yyy.com/auth
Assertion Consumer Service URL: http://zzz:1111/AuthServices/Acs
I have created a self-signed certificate and added it to the local project.
The local configuartion:
<kentor.authServices entityId="https://xxx.yyy.com/Files/Metadata/IdP/Saml"
returnUrl="http://localhost:8585/">
<identityProviders>
<add entityId="https://xxx.yyy.com/"
signOnUrl="https://xxx.yyy.com/Saml/Login.aspx"
allowUnsolicitedAuthnResponse="true" binding="HttpRedirect">
<signingCertificate fileName="~/App_Data/SelfSignedCertificate-2016-01-10-22-37.cer" />
</add>
</identityProviders>
<federations>
<add metadataLocation="http://localhost:52071/Federation" allowUnsolicitedAuthnResponse="true" />
</federations>
</kentor.authServices>
I will appreciate any kind of help as i'm stuck with this.
Thanks
Gilad
The first entityId, in the kentor.authServices root element should be the identifier you use for your site. Typically http://zzz:1111/AuthServices, which is the ACS url minus the last part.
The signingCertificate within the identityProviders/add element should not be your own certificate, but the certificate that the Idp uses to sign messages.
The federations element should be completely removed. It points to the local development environment, that it looks like you've copied the config from.

Jenkins and SAML plugin issues using SSO Auth

Jenkins v 1.597
SAML plugin v 0.3
We are using an internal PingFederated server and I have entered the xml metedata contents into the Security configuration of Jenkins.
I have tried on two servers, one set up HTTPS (SSL) and one just HTTP.
We get errors when trying to login using SSO that pertain to the https://servername/securityRealm/finishLogin redirect and the same for non-SSL server.
We are stumped on what to check here, the PingFederated administrator has it set for the postback to the securityRealm/finishLogin URL, which is what is in the code for the plugin, we just are not sure how to proceed.
The contents of the xml metadata:
<md:EntityDescriptor ID="MNkL_uYrUsdEca2oWqH6gdgG4t3" cacheDuration="PT1440M" entityID="ACIWW:Saml2:POC" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" WantAuthnRequestsSigned="false"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data> <ds:X509Certificate>CERTIFICATECODE HERE</ds:X509Certificate></ds:X509Data> </ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://SSOSERVERNAME/idp/SSO.saml2"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://SSOSERVERNAME/idp/SSO.saml2"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://SSOSERVERNAME/idp/SSO.saml2"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://SSOSERVERNAME/idp/SSO.saml2"/></md:IDPSSODescriptor><md:ContactPerson contactType="administrative"><md:Company>COMPANYNAME</md:Company></md:ContactPerson></md:EntityDescriptor>
Any help or suggestions would be greatly appreciated.
John

httpOnly cookie

I had done web scan for an application(built in struts and hibernate framework) deployed in jboss 5 which reported "Set-cookie does not use HTTPOnly keyword. The web application does not utilize HTTPOnly cookies". What does it mean. I looked for some post and just added one line in my jboss/deploy/jbossweb.sar/context.xml as
<SessionCookie secure="true" useHttpOnly="true" >
After setting that, I am getting error while running the application. Is there any configuration that I am missing?
try this:
<SessionCookie secure="true" httpOnly="true" />
What does it mean
The HttpOnly flag in a http response header indicates to the browser that client-side access to the JSESSION_ID or other session-cookie type identifier should not be permitted. What this is intended to prevent is a malicious access to the session token via client side scripts in an XSS(or other attack involving session hijacking from the client side). Currently almost all major browsers support this flag(see this list for supporting browsers), but it's simply ignored in browsers that don't support it. See more info on this at the OWASP site
Setting it up is similar for tomcat and forks of it, including Jboss, by including the following in your context file:
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
or
<SessionCookie secure="true" httpOnly="true" />