NiFi SSO using KNOX: Error when requesting certificate - single-sign-on

I was configuring KNOX SSO to secure NiFi follow this document and got an error when requesting certificate Token does not meet minimum size of 16 bytes.
root#hadoop:/home/knox# /home/hadoop/nifi/config/nifi-toolkit/bin/tls-toolkit.sh client --subjectAlternativeNames "CN=hostname.org, OU=KNOX" -F -f /home/knox/nifi-ca-config.json
2019/09/25 14:14:17 INFO [main] org.apache.nifi.toolkit.tls.service.client.TlsCertificateAuthorityClient: Requesting new certificate from cityhub.bigdatacenter.org:10443
Service client error: java.security.GeneralSecurityException: Token does not meet minimum size of 16 bytes.
Usage: tls-toolkit service [-h] [args]
Services:
standalone: Creates certificates and config files for nifi cluster.
server: Acts as a Certificate Authority that can be used by clients to get Certificates
client: Generates a private key and gets it signed by the certificate authority.
status: Checks the status of an HTTPS endpoint by making a GET request using a supplied keystore and truststore.
This is the content of /home/knox/nifi-ca-config.json
{
"dn" : "CN=hostname.org, OU=KNOX",
"domainAlternativeNames" : null,
"keyStore" : "/home/knox/knox-nifi-keystore.jks",
"keyStoreType" : "jks",
"keyStorePassword" : "admin",
"keyPassword" : "admin",
"token" : "token",
"caHostname" : "hostname.org",
"port" : 10443,
"dnPrefix" : "CN=",
"dnSuffix" : ", OU=NIFI",
"reorderDn" : true,
"trustStore" : "/home/knox/knox-nifi-truststore.jks",
"trustStorePassword" : "admin",
"trustStoreType" : "jks"
}

The error message says "Token does not meet minimum size of 16 bytes." so you probably need to change the token field in your config json to be 16 characters, right now you have just "token".

Related

Configure remote-user name in Wildfly OIDC

I successfully configured Wildfly 26 to authenticate via Keycloak following the usual tutorial. Example: https://www.youtube.com/watch?v=2gQO4_7Z5CI
It works as announced - when required the user's browser gets redirected to keycloak, after login it redirects back. That much for authentication. I also checked that the authorization can be performed by running request.isUserInRole(...) which is true if and only if in keycloak some role was associated to that user. That much for authorization.
But the methods request.getRemoteUser() and request.getUserPrincipal().getName() only return the keycloak's userid, which looks like 896128e8-3260-42c8-9457-3c8ee236eb4d.
How can I make Wildfly OIDC to report the username by looking at the preferred_username token claim?
So I learned that Wildfly's OIDC client can be configured to read the principal name from another token claim. For this it was sufficient to add the line
"principal-attribute": "preferred_username",
into my web application's WEB-INF/oidc.json. This is the only line required on top of the configuration generated by Keycloak:
{
"principal-attribute": "preferred_username",
"realm" : "myrealm",
"auth-server-url" : "http://localhost:8180/",
"ssl-required" : "external",
"resource" : "webapp",
"credentials" : {
"secret" : "7BqGXjt7cw6p88DNoiXCi1663bIzKPwY"
},
"confidential-port" : 0
}
When authenticating, the tokens emitted by Keycloak are exactly the same however the client uses the specified field's value instead of the sub value.
From the documentation:
principal-attribute
OpenID Connect ID Token attribute to populate the UserPrincipal name with. If token attribute is null, defaults to sub. Possible values are sub, preferred_username, email, name, nickname, given_name, family_name.

JWT token exchange via named credentials as per user

I am trying to generate a JSON Web Token(JWT) via named credentials as per user.
I want to use this named creds for authentincation purpose. So that using them after salesforce providing JSON web token, in exchange my local auth server will provide a token.
Below are the settings I have added while creating the named credentials as per user.
Label : TestJWTCredential
Name : TestJWTCredential
URL : -> external-endpoint <-
In Authentication Part
Certificate : MulesoftJWT
Identity Type : Per User
Authentication Protocol : JWT Token Exchange
Token Endpoint Url : http://localhost:8091/api/provider/token
Scope : refresh_token full
Issuer : -> my-username <-
Per User Subject : $userId
Audience : http://localhost:8091/api/provider/token
Token Valid for : 1 Hours
JWT Signing Certificate : MulesoftJWT
Ref :- https://help.salesforce.com/articleView?err=1&id=sf.named_credentials_about.htm&type=5#language-combobox
"http://localhost:8091/api/provider/token" This is the url of my authorization server which is a mule application deployed on my local.
Also while calling this named creds from developer console, it gives this error
System.CalloutException: Unable to complete the JWT token exchange.
Below is the APEX code,
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:TestJWTCredential/services/oauth2/userinfo');
req.setMethod('GET');
req.setHeader('Authorization', 'Bearer'+ UserInfo.getSessionId());
Http http = new Http();
System.debug('REQUEST :::: ' + req);
HTTPResponse resp = http.send(req);
System.debug('RESPONSE :::: ' + resp.getBody());
Can any body help me how to do it.
I was just viewing some Salesforce videos on this topic. In the "Deep Dive into Salesforce Connected App - Part 3" video, at the 23:56 mark, the Salesforce presenter had to delete the "scope" value to get it to work. https://youtu.be/wN8d4vwSA-E?t=1436

WSO2 identity server - SAML2 Response Issuer verification failed

I am using the wso2 sample apps (saml2-web-app-pickup-dispatch and saml2-web-app-pickup-manager) to test single sign on through WSO2 identity server version 5.10.0
The deployment is fine and on clicking the application's login, it redirects to the WSO2 login page successfully.
User logs in successfully but receives error below.
HTTP Status 500 – Internal Server Error
Type Exception Report
Message SAML2 Response Issuer verification failed
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.wso2.carbon.identity.sso.agent.exception.SSOAgentException: SAML2 Response Issuer verification failed
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processSSOResponse(SAML2SSOManager.java:569)
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processSSOResponse(SAML2SSOManager.java:525)
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processResponse(SAML2SSOManager.java:358)
org.wso2.carbon.identity.sso.agent.SAML2SSOAgentFilter.doFilter(SAML2SSOAgentFilter.java:98)
Note The full stack trace of the root cause is available in the server logs.
Apache Tomcat/8.5.53
Logs from the server
TID: [-1234] [2020-04-25 19:16:55,881] [7e977cfd-8304-44ba-ab4f-4644baff988e] INFO {AUDIT_LOG} -
Initiator : wickrema | Action : Login | Target : ApplicationAuthenticationFramework |
Data : {
"ContextIdentifier" : "51f93b05-68cf-4bf4-b62b-51e3e2502889",
"AuthenticatedUser" : "wickrema",
"AuthenticatedUserTenantDomain" : "carbon.super",
"ServiceProviderName" : "saml2-web-app-pickup-dispatch",
"RequestType" : "samlsso",
"RelyingParty" : "saml2-web-app-pickup-dispatch.com",
"AuthenticatedIdPs" : "eyJ0eXAiOiJKV1QiLCAiYWxnIjoibm9uZSJ9.eyJpc3MiOiJ3c28yIiwiZXhwIjoxNTg3ODMxNDE1ODA0MzAwMCwiaWF0IjoxNTg3ODMxNDE1ODA0LCJpZHBzIjpbeyJpZHAiOiJMT0NBTCIsImF1dGhlbnRpY2F0b3IiOiJCYXNpY0F1dGhlbnRpY2F0b3IifV19."
} | Result : Success
Your Service Provider application(Pickup-Dispatch) is trying to verify if the received SAML response is issued by the expected SAML Identity Provider. WSO2 includes its ID in the SAML response's <saml:Issuer> tag.
Your application has a pre-configured entity ID for WSO2 in the saml2-web-app-pickup-dispatch.com/WEB-INF/classes/sso.properties file as below.
SAML2.IdPEntityId=localhost
Likewise, WSO2 IS populates its SAML response's issuer with the value you've configured in the Resident Identity Provider's Home Realm Identifier.
But you can override the Home realm identifier with the IdP Entity ID Alias of your Service Provider SAML configurations as below.
Bottom line, the Issuer ID of the SAML response should be the same as what you've configured in the Application as the IdP Entity ID.
Change either value to make them the same.
Code for your reference

Grails mail Exchange server configuration

I'm trying to configure mail with an Exchange server.
This is my configuration
grails {
mail {
host = "mail.xxx.xx.xx"
port = 443
username = "username"
password = "password"
props = [ "mail.smtp.auth":"true",
"mail.smtp.port":"443",
"mail.smtp.ssl.enable" :"true"
]
}
}
I'm getting the following error
Message: org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketException: Connection reset. Failed messages: javax.mail.MessagingException: Exception reading response;
I know it's an issue with the props that I have to change, since this configuration works on my mail app.
I know that the port is correct, it uses SSL.
I also tried using these props
props = ["mail.smtp.timeout" : "100000",
"mail.smtp.starttls.enable" : "true",
"mail.smtp.EnableSSL.enable" : "true",
"mail.transport.protocol" : "smtps",
"mail.smtp.socketFactory.port" : "443",
"mail.smtp.auth" : "true",
"mail.smtp.socketFactory.class" : "javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback": "false",
"mail.debug" : "true"]
The debug result it this :
DEBUG: JavaMail version 1.5.1
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "xxx.xxx.xx.xx", port 443, isSSL true
It looks to me as a certificate problem. If you have access to a server not using SSL, I would test that first, otherwise you should:
Find the certificate issuer (If you don't know it, you could use openssl verify http://www.herongyang.com/Cryptography/OpenSSL-Certificate-Path-Validation-Tests.html)
Look a CA in your java keystore
Locate Either the default java keystore (How do I find out what keystore my JVM is using?) or the one you are using
List the keystore and look for a corresponding CA
If there is a CA then the problem is not likely to be this
If there is no corresponding CA, then obtain the CA certificate and import it to you keystore, restart the server, and should work again.
I had the very same issue a while back. If you are trying to access an exchange server within a network (organization), I believe the port number is the issue here. It could have been changed by the network admin.
Please contact the network administrator and explain to him that you are trying to access the Exchange Server and require the username, password and the relevant port number. Authentication could be optional if the app is run in-house, i.e.
props = ["mail.smtp.auth":"false"]
I hope this helps.

403 User Rate Limit Exceeded and 401 Invalid Credentials - Google Analytics API v3

We were able get the data from Google Analytics using Oauth2.0, but now suddenly we are getting 403 User Rate Limit Exceeded and 401 Invalid Credentials.
On server start up we are getting,
SEVERE: unable to refresh token
com.google.api.client.auth.oauth2.TokenResponseException: 403 User Rate Limit Exceeded
and for subsequent requests it is giving,
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
I have tested access token with following url :
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxxxxxxx
I am getting valid access token message, but still i am getting Invalid Credentials. I have also tried with OAuth2 playground, here also i am getting same message.
Any help to resolve this issue.
Make sure you are caching the access tokens and that you are making a reasonable number of refresh requests. Refreshing in a tight loop (or too frequently from multiple threads or servers in a cluster) for the same user will lead to 403.
The 401 error is most likely due to the fact that getting a new access token failed and you are using an expired one.