Is there a way to prevent MPJwt authenticating unprotected / permitted endpoints. Using Openliberty server - open-liberty

Mpjwt configuration for open liberty server.xml
<mpJwt
id="keycloakJwt"
jwksUri="https://auth.ura.go.ug/auth/realms/sso/protocol/openid- connect/certs"
issuer="https://auth.ura.go.ug/auth/realms/sso"
userNameAttribute="preferred_username"
audiences="askura-etax-ws">
</mpJwt>
Unprotected route return the following error when accessed CWWKS5522E: The MicroProfile JWT feature cannot perform authentication because a MicroProfile JWT cannot be found in the request.
#PermitAll
#Path("/test")
public class TestResource {
#Inject
AppProperty appProperty;
#GET
#Path("/ping")
#Produces(MediaType.TEXT_PLAIN)
public String test() {
return "TEST";
}
}

The code around the CWWKS5522E message was recently updated in https://github.com/OpenLiberty/open-liberty/pull/15606 in 21.0.0.2 to not be issued when the resource is unprotected. Please confirm if you are using at least that release or a newer one. If you are, please open an issue in https://github.com/OpenLiberty/open-liberty/issues and we can assist you in debugging your problem.
Regards,
Teddy

Related

springboot swagger3 "Failed to load remote configuration."

Spring Boot 2.6.3 with Springdoc.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.5</version>
</dependency>
In applicaton.yaml, when I set the path as /v3/api-docs or remove it, that means use the default path "/v3/api-docs".
The Swagger UI page shows up correctly with the APIs
http://localhost:8080/swagger-ui/index.html
But I want to overite the path as below
api-docs.path: /bus/v3/api-docs
then Swagger UI displays the "Failed to load remote configuration" error:
Make sure to add "/v3/api-docs/**" in configure method.
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui/**", "
/v3/api-docs/**");
}
}
If you are using Spring Security in your app, you must include the URL in the configs.
Add the code below please to your project.
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui/**", "/bus/v3/api-docs/**");
}
}
I had the same problem, If you are behind a reverse proxy, the fix was to add the following property in application.yml
server:
forward-headers-strategy: framework
this is needed due to the following
Swagger relies on internal routing to make requests from the clients perspective. Putting the service behind a reverse-proxy without providing the X-Forwarded headers will result in the user not being able to use the documentation as intended
source -> https://medium.com/swlh/swagger-spring-boot-2-with-a-reverse-proxy-in-docker-8a8795aa3da4
Perform "Empty cache and hard refresh" in your browser.
I think I have solved the problem (thanks to #Ivan Zaitsev), just wanted to add more clarification to the answer.
I too have changed the api-docs.path property and I had the same problem. When I inspect the requests on swagger UI page, swagger-config request returns 404 since it was still trying to get the config from the old URL.
Even though I have changed api-docs.path property, here is the request URL that tries to retrieve swagger-config.
http://localhost:8080/api/v3/api-docs/swagger-config
It turned out to be a problem related to openapi-ui, because I was able to solve it when I cleared the browser cache and cookies. It is better do to the tests with incognito browser since it does not hold any data on the session.
If you are using SpringBoot v3, you must use springdoc-openapi v2:
https://springdoc.org/v2/
With gradle, for example:
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

OAuth2 Spring Security 5.2.x from Spring Security Oauth 2.x access authenticated oauth/token_key getting 403

When calling
oauth/token_key
To retrieve the OAuth public key for example
{
"alg":"SHA256withRSA",
"value":"-----BEGIN PUBLIC KEY----- nMAABIjANBgkq… -----END PUBLIC KEY-----"
}
How do we pass the credentials when calling this via Spring OAUTH.
Previously it seems these properties were set with
security.oauth2.resource.jwt.key-uri=http://localhost:8080/oauth/token_key
security.oauth2.client.client-id=clientID
security.oauth2.client.client-secret=clientPassword
In the migration guide I cannot see any appropriate migration for this or via the config.
As we now use config like this I believe to set the jwt.key-uri
spring.security.oauth2.client.resourceserver.jwt.jwk-set-uri=
But no equivalent place to set any id or secret.
Thanks
So it is probably an edge case that a public key is protected like this and legacy OAuth server. I could not find any documentation at this time to describe a solution that worked. It does seem like that Spring Security OAuth is in a large transition. I did not want to roll back to deprecated code so I defined my own bean for the NimbusReactiveJWTDecoder.
This allowed me to pass basic auth when getting the public key at start up time of the application.
Sample code in Koltin is:
#Bean
fun jwtDecoderByPublicKey(webclient: WebClient): NimbusReactiveJWTDecorder? {
webclient
.get()
.headers { headers -> headers.setBasicAuth("username","password") }
.retrieve()
.bodyToMono<>()
.map {
KeyFactory.getInstance("RSA")
.generatePublic(X509EncodedKeySpec(getKeySpec(it.value))) as RSAPublicKey
}
.map {
NimbusReactiveJWTDecoder.withPublicKey(it)
.signatureAlgorithm(SignatureAlgorithm.form("RS256")).build()
}.block()
Code inspired by the auto configuration bean if property given.
Current best solution I can find.

Unable to access spring-docs-open-ui swagger documentation

I am a spring newbie trying to configure swagger documentation for my spring boot application. I configured my application based on the documentation provided here
I am able to access the documentation page locally from this URL
http://localhost:8080/doc.html
However, when I deploy my application on Docker I keep getting a 404 status.
https://www.mywebsite.com/context_path/doc.html
My application.properties file looks like this -
springdoc.api-docs.path=/doc
springdoc.swagger-ui.path=/doc.html
I have also added a HomeController which redirects to the documentation page
#Controller
public class HomeController {
private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class);
#RequestMapping(value = "/")
public void redirect(HttpServletResponse response) throws IOException {
response.sendRedirect("/doc.html");
}
}
FYI, I am using Amazon Cognito. I have read and tried several examples that I found online but I cannot make this work. Can someone help me?
You are using only #Controller annotation;
If you are using REST APIs, you should use #RestController.
If you need to use #Controller, you should add #ResponseBody
If you don't want change your #Controller, you add:
static {
SpringDocUtils.getConfig().addRestControllers(HelloController.class);
}
More information are available on the documentation of F.A.Q:
https://springdoc.org/faq.html#my-rest-controller-using-controller-annotation-is-ignored

Azure Active Directory with Springboot : how to handle expired oauth token?

I have a springboot app which use Microsoft Azure active directory to allow authentication (oauth2).
I have followed the "how to" provided by Microsoft (https://learn.microsoft.com/en-us/java/azure/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?view=azure-java-stable).
Everything is working well except that I have no ideas on how to handle expired token (after 1 hour) in a way that it will not affect the users.
I know that it is possible to get new token with the refresh token but if I take a look in NimbusAuthorizationCodeTokenResponseClient.java the refresh token is not saved anywhere even if it's available.
I don't find any examples on how to keep this refresh token and how to use it, like if it was supposed to work automatically like the whole process.
Can someone have any experience with this Azure Active directory spring boot module?
I'm using Springboot 2.0.4 with azure spring boot module 2.0.5
Your access_token gets automatically refreshed by the refresh_token.
But when your refresh_token token expires you can still run into the same error. To handle it you can make your refresh_token automatically renew the same time you get a new access_token. Use reuseRefreshTokens(false) in the configuration of AuthorizationServerEndpointsConfigurer at the auth-server code:
Take a look at the refreshAccessToken method in the DefaultTokenServices class:
public OAuth2AccessToken refreshAccessToken(String refreshTokenValue,
TokenRequest tokenRequest) {
// Omitted
if (!reuseRefreshToken) {
tokenStore.removeRefreshToken(refreshToken);
refreshToken = createRefreshToken(authentication);
}
// Omitted
}
You should somehow set the reuseRefreshToken flag to false. You can do that in your AuthorizationServerConfigurerAdapter implementation:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
// Other methods
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.reuseRefreshTokens(false);
}
}

forcing the Jersey Grizzly server to authenicate

I am performing acceptance tests against REST services written using Jersey. In my services, I need to get the name of the user who successfully authenticated (BASIC) using:
#Context private SecurityContext securityContext; //at class level
String username = securityContext.getUserPrincipal().getName() //inside a resource
I am using the Jersey client API and running against the Grizzly server. I set up the server as follows:
public class BaseResourceTest extends JerseyTest {
public BaseResourceTest() throws Exception {
super(new WebAppDescriptor.Builder("net.tds.adm.na.batchcut")
.contextPath(baseUri.getPath())
.contextParam("contextConfigLocation","classpath:testContext.xml")
.initParam("com.sun.jersey.api.json.POJOMappingFeature",
"true").servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class)
.build());
}
.......
}
In my tests, I pass an authorization header as follows:
WebResource resource = resource().path(_url);
return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HttpHeaders.AUTHORIZATION, new String(Base64.encode("judge:smails"))).post(ClientResponse.class, _formData);
However, in my resources I get an NPE when trying to get the user name. I think I need to get the server to actively authenticate against a realm but I haven't found how to configure the server to do this. Has anybody had any experience with this?
Unfortunately Grizzly HttpServer doesn't support authentication at the moment.
But here you can find a simple example how to implement authentication using Jersey Filter.
http://simplapi.wordpress.com/2013/01/24/jersey-jax-rs-implements-a-http-basic-auth-decoder/

Resources