Gmail SMTP works in SpringBoot but not on Tomee Server - spring-boot

I am using exactly the same settings for javax Mail session, which works like charm in SpringBoot App but fails in Tomee Server.
On SpringBoot's application.properties, I have the following settings (which works):
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<my gmail>
spring.mail.password=<App PW generated on Google>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
And here are the setting in Tomee's conf/tomee.xml settings
<Resource id="mail/bjm" type="javax.mail.Session">
mail.smtp.host=smtp.gmail.com
mail.smtp.starttls.enable=true
mail.smtp.port=587
mail.transport.protocol=smtp
mail.smtp.auth=true
mail.smtp.user=<my gmail>
password=<App PW generated on Google>
</Resource>
On Tomee, when I run the application, I get the following error message:
failure (javax.mail.AuthenticationFailedException: null)
I am puzzled what wrong am I doing in tomee.xml because I have followed the guidelines from here: https://tomee.apache.org/master/docs/configuring-javamail.html
How can I fix the issue?

The sample you "state" you are following Declaring a JavaMail Resource which you aren't really since you have changed it.
Is for use with MAP SASL XOAUTH2 mechanism configuration Xoauth2 is a form of oauth2 that is supported by googles imap server.
rather then following the sample you have changed it to use user name and an apps password. This is not Xoauth2.
Offending lines of code:
spring.mail.username=<my gmail>
spring.mail.password=<App PW generated on Google>
You are getting a fail for javax.mail.AuthenticationFailedException because you have not added a valid access token as shown in the sample, which you have not shown in your code.
store.connect("imap.gmail.com", "<username>#gmail.com", "<YourAccesToken>");
To be 100% clear an apps password is not an access token an access token must be created by standard Oauth2 mechanizes of requesting authorization of the user, with a mail scope.

Related

Spring boot application with Azure AD throws Reply URL does not match

I have a spring boot application integrated with Azure AD SAML login. I have followed this sample to achieve this. It works fine in localhost but on deployment to a prod url, it keeps giving below error
the redirect uri that I see in the authorization request URL starts with http. This is contradictory because Azure App Registration does not allow to configure any non https URLs and only exception is localhost.
In order to match URLs, I tried editing App Registration's manifest in Azure portal to make it http. Now, it seems URLs match but then I get below error:
I have also tried setting https URL both on azure portal and application.properties using "azure.activedirectory.redirect-uri-template" as mentioned in stack overflow post here but that also does not work.
I have also gone through this post but that also didn't help.
Any help would be much appreciated.
In order to solve the error of redirecting to https but the redirect_uri in request still starts with http, there are two similar issues:
1. The HTTPS requests terminate at the proxy and the proxy then uses HTTP protocol to communicate to your Tomcat server. You will face this if you deploy your code on cloud providers like App Service. Answer is here.
In application.properties:
security.oauth2.client.pre-established-redirect-uri=https://yourappurl.net/login
security.oauth2.client.registered-redirect-uri=https://yourappurl.net/login
security.oauth2.client.use-current-uri=false
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.use-relative-redirects=true
server.use-forward-headers=true
server.tomcat.internal-proxies=.*
2. Add server.forward-headers-strategy=native in applications.properties. Answer is here. For more about this setting, see here.

Spring Security OAuth2 supporting Facebook appsecret_proof

I am able to login with Facebook into my SpringBoot application only if I disable the "Require App Secret" option in the Facebook Developer application configuration.
When the extra (recommended) security check is enabled I get an error
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_user_info_response]
An error occurred while attempting to retrieve the UserInfo Resource: Error details: [UserInfo Uri:
https://graph.facebook.com/me?fields=id,name,email, Error Code: {message=API calls from the server
require an appsecret_proof argument, type=GraphMethodException, code=100, fbtrace_id=xxxx}]
It is evident that Spring Security tries to access Facebook (calling https://graph.facebook.com/me?fields=id,name,email) to retrieve the authenticated user but it fails to pass the extra parameter appsecret_proof.
It is not immediately clear (after digging into SpringSecurity documentation and forums) how I can let Spring add the extra token.
I had a very similar situation - I could not log in to my application using the facebook user account.
First make sure that the given client id and secret id are correct (sometimes it can be confused with your other project). If you are sure that the entered data is okay, I would start by checking the available permits. So open the facebook login plugin panel (you should have a tab on the right side of the screen).
For my case, the following configuration was sufficient:
What's more, check the available permission and features:
public_profile access is required to extract basic information of a user who wants to log in to your website. In addition, it is also worth adding an email request.
Also check the configuration for the facebook client, which allows you to get the user token:
spring:
security:
oauth2:
client:
registration:
facebook:
clientId: your-client-id
clientSecret: your-client-secret
redirectUri: "{baseUrl}/api/oauth2/callback/{registrationId}" # Note that facebook now mandates the use of https redirect URIs, so make sure your app supports https in production
scope:
- email
- public_profile
provider:
facebook:
authorizationUri: https://www.facebook.com/v3.0/dialog/oauth
tokenUri: https://graph.facebook.com/v3.0/oauth/access_token
userInfoUri: https://graph.facebook.com/v3.0/me?fields=id,first_name,middle_name,last_name,name,email
In my case, the above configuration was enough for the user to authorize himself on an external website.

Spring Cloud Config Server - Connect to Github account with 2FA

I'm trying to create a Spring Cloud Config Server to retrieve configuration files from a private GitHub repository. My GitHub account has 2 Factor Authentication activated so I wasn't expecting the below configuration to work, which it didn't but I can't find any documentation to suggest what I need to do in order to make it work.
What configuration do I need to set that will allow the connection to work?
spring.cloud.config.server.git.uri=https://github.com/DanBonehill/photo-app-config
spring.cloud.config.server.git.username=USERNAME
spring.cloud.config.server.git.password=PASSWORD
Error
org.eclipse.jgit.api.errors.TransportException: https://github.com/DanBonehill/photo-app-config: not authorized
What you could try and do (have not tested this), is create a personal access token from the Github console.
Then configure
spring.cloud.config.server.git.username=<yourusername>
spring.cloud.config.server.git.password=<yourtoken>
Instead of using username and password you should use an ssh key, the official documentation can guide you through it!
Basic authentication using a password to Git is deprecated and will soon no longer work. Visit https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information around suggested workarounds and removal dates.
you solve this in 2 minutes, this problem is because at August 13, 2021 the github update the login form, to solve this.
1) login in your gitHub folow this path: Settings > Developer settings > Personal access tokens > Generate new token
2) Now set a long time to expiration token, check the "repo" to allow access repository with this token, and Generate token.
3) Now skill your github password because this token created is your new password, replace this at all application, server, terminal that need to access github.
4) Now configure your spring configuration server, this is a content of file "application.properties" of spring configuration server at path /src/main/resources/application.properties.
spring.cloud.config.server.git.uri= https://github.com/"username"/"repository" //your githur repository
spring.cloud.config.server.git.search-paths= myFilesFolder /if your files is into some folder
spring.cloud.config.server.git.username= testUsername // your username
spring.cloud.config.server.git.password= gti_FdsweecSoUSHPsdfw //Here is your new token created

Changing SSL Certificate and associated domain gives a 401 when it didn't before

I have an application with multiple services. One of them is the auth service that takes care of creating the jwt after checking that the client id (i.e. browser or app) is valid and provided username/password is also valid.
I have another service (gateway) that redirect to other services any requests from the users using the jwt token for authentication.
All this works and has been working for a few years. It is based on Spring Boot using Spring Security (starter v2.1.5). It is soon time to renew our certificate and at the same time move to our new domain. The new certificate has been applied to the Google Cloud Platform load balancer.
The call for health check using the Spring Actuator is responding with the proper "UP" (in json) response. When I try to make the call from same Postman request (with new domain name used) I get the following response with a 401 code:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
I do have the proper clientid and password/secrete encoded using base64 (hey it worked before and nothing else was changed).
I tried to debug setting #EnableWebSecurity(debug = true), but it generates zero logs from the request.
If I switch back the certificate to old one (and old domain), it works again without any other changes. This has been driving me a bit on the crazy side to say the least. Any help, suggestion, ideas would be appreciated.
It ended up being an error on my part. When I added a A class resources during the copy paste of Load Balancer IP, I put the same IP for both of my services (i.e. one of the copy didn't stick). Ending up in calling security on the gateway service when asking for the auth token.
Thanks for the comment #Boris-Treukhov

Spring Security Kerberos SSO for a REST API (Tomcat)

Here is my problem:
Context :
-Windows Server 2012 with ActiveDirectory
-Tomcat
-Rest API (Spring)
I'm currently trying to restrict REST request. I want that only specific groups of the AD could access to specific resources. I'm restricted to Kerberos authentication.
System configuration
Create a user in domain "Tomcat"
setspn -a HTTP/apirest.domain#DOMAIN
Generate a tomcat.keytab using ktpass
API rest configuration
I'm using the spring security sample on github that you can find here :
https://github.com/spring-projects/spring-security-kerberos/tree/master/spring-security-kerberos-samples/sec-server-win-auth
I know that there is an EntryPoint and this is not needed in my context (API Rest). I've chosen this sample because it seems to use the windows authentication context and use it to automatically authenticate me in the spring security context. Right after, an ldap request is send to extract all information about the user logged. In my case, I need to extract the group.
I'm also using :
https://github.com/GyllingSW/kerberos-demo
To extract the role of the user with the class "RoleStrippingLdapUserDetailsMapper.java" instead of the "ActiveDirectoryLdapAuthoritiesPopulator". This implementation also offers localhost authentication but the issue with the NTLM token seems to be fixed in last commit of spring security.
I'm not really sure if this is the right way to do what I want.
My authentication seems to fail and I only have one things going wrong in my logs..
"Property 'userDn' not set - anonymous context will be used for read-write operations"
Questions
Do I have to run my tomcat service using the tomcat account ? (Seems to be, yes)
Am I doing the right things with Kerberos security ?
How can I get rid of the anonymous context?
The anonymous context seems to be set just right after Tomcat start. I want to get a context just after that my user (For instance, user1) requests the rest API (EntryPoint or whatever)
If there is something unclear let me know, I will try to reformulate!
Thanks,
You do not need to query LDAP to get information about which groups does user belong to. Active Directory already adds this information to the Kerberos ticket which is sent from browser to Tomcat.
You just need to extract this information from the token for example using Kerb4J library. It comes with Spring integration inspired by spring-security-kerberos project so it should be pretty easy to switch to it.
If you still want to query LDAP you need to authenticate in LDAP before you can make any queries. Again there's no need to use end-user accounts for it - you can use the keytab file for Kerberos authentication in LDAP and query groups using "Tomcat" account
I found a way to fix my issue.
In a REST API context, you have no entry point. I tried to set my entry point to an unmapped URL, just to do the negociation. By doing this, you will receive an HTTP response with the error code 404 (Not found) but with the right header was added by spring security (WWW-Authenticate).
The web browser will not send the ticket service if the error code is not 401.
To solve this problem, you have to create a CustomEntryPoint class (implements AuthenticationEntryPoint) and you need to override the "commence" method to return a 401 HTTP code with the right header.
I hope that could help. If there is a better way, let me know !

Resources