I've looked at the Oauth2 workflow on Google's docs and it seems pretty intuitive. Using a basic servlet I understand how I'd process all the callbacks, but using Spring Boot I'm a little confused by what I need to do if I'm using oauth and the Spring security module.
I found a tutorial here describing how to add authentication using a username and password, but I'm not sure if this is the best option for my needs as I mostly want to restrict things in the page and not the page itself. Anyway, assuming I will need authentication per page how can I set up a user using Oauth? Looking at the tutorial it appears the security module is doing some magic to get the username/password checked against the in-memory database.
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
In the example above I see configureGlobal sets up the username/password store to check against. Does spring boot have hard-coded logic for a username/password that will prevent me from using it for Oauth2? Should I just ignore this security module and set the user directly using my own handlers?
If all you need is to know who Google thinks your user is, you are happy to handle everything yourself you don't necessarily need Spring Security. There is also a Spring Social Google library here that you could use to implement the callbacks.
Related
I am running into a problem with calling a REST endpoint on a server, using a REST client in Quarkus, built with the org.eclipse.microprofile.rest.client.RestClientBuilder. I would very much like to debug the service, by writing the HTTP requests and responses to the log, so I might see what is actually being sent to the server. The hunt for a guide for that particular issue has eluded me however.
I managed to build a logging filter but that only logs out the URL and the Entitys toString value, which is not at all the same as the HTTP request and response being sent.
Help me by pointing me to a solution to log the actual HTTP request and response.
You can try to enable the logging for all the traffic including wire or just some components, here in the logging configuration guide you can find how enable just some components logging.
Add this to your application.properties and you should be able to see some logging information quarkus.log.category."org.apache.http".level=DEBUG
If you need to log everything you can always put quarkus in debug level ALL, and the pick the components you need to constraint the logging, whit this you see all the traces at wire level.
You can also enable the http access log with this guide
Good luck.
If you are using resteasy reactive you can turn on logging with:
quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.logging.body-limit=1024
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
Check this: https://quarkus.io/guides/resteasy-reactive#the-jax-rs-way
Simply implement that class and you will start logging. Like this:
#Provider
class LoggingFilter implements ContainerRequestFilter,
ContainerResponseFilter {
/* Useful stuff for later development purposes.
#Context
UriInfo info;
#Context
HttpServerRequest request;
*/
#Override
public void filter(ContainerRequestContext requestContext) {
Log.info(requestContext);
}
#Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
Log.info(responseContext);
}
}
Then you may use UriInfo, HttpServerRequest and ContainerRequestContext to get any data you want and add to your custom log.
I've been banging my head against this issue now for a couple days and I'm a bit of a noob with spring security. When implementing Auth0 into the system following their tutorials I get some unexpected behavior. When making a request to api if I have the configuration paramater
auth0.defaultAuth0ApiSecurityEnabled = false
then the when I do the OPTIONS pre-ping, I get back a 401 unauthorized code. This doesn't make much sense to me since OPTIONS requests don't get a token injected. To make matters more confusing for me if I switch this flag to true then the OPTIONS preping returns a 200 and then the get request to my endpoint returns 404. This seems hopeful, but the documentation explicitly says that the auth0.defaultAuth0ApiSecurityEnabled configuration should be set to false.
I have the config set up according to their spec as well.
#Configuration
#EnableWebSecurity(debug = true)
#EnableGlobalMethodSecurity(prePostEnabled = true)
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebConfig extends Auth0SecurityConfig {
/**
* Our API Configuration - for Profile CRUD operations
*
* Here we choose not to bother using the `auth0.securedRoute` property configuration
* and instead ensure any unlisted endpoint in our config is secured by default
*/
#Override
protected void authorizeRequests(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api).authenticated()
.antMatchers("/**").permitAll();
}
}
I have intentionally set up the endpoint I am trying to hit as non secured as well which has made 0 difference in accessibily. Can anyone shed some light on where they think I might be going wrong with this in Spring security?
In JAX-RS (or Jersey) REST service, I'm trying to make custom authentication for my users in database.
Currently I have #GET annotated method which should interact with user asking for credentials just like it is done in Spring framework with authentication provider - no custom login form, just plain HTTP login with browser popup form.
Currently I can handle HTTP Basic Access Authentication provided in header, but I need to ask for credentials before accessing content interactively and then make token-based authentication on this base.
I have to keep the application light-weight but I don't know how can this "easy" task be done..
Edit: I found something in Wildfly configuration (I'm using 9 Final version) but I don't know how to use it for login using datasource..
If you already can handle HTTP Basic authentication, then you only need to get a a "login form" from the browser? We solved this by implementing an javax.ws.rs.ext.ExceptionMapper and overriding toResponse(Throwable ex). Our app throws a NotAuthenticatedException which gets mapped to javax.ws.rs.core.Response.Status.UNAUTHORIZED. Then we add a response header appropriately:
#Provider
public class RESTExMapper implements ExceptionMapper<Throwable>
{
#Override
public Response toResponse(Throwable ex)
{
//our application maps a not logged in exception to javax.ws.rs.core.Response.Status.UNAUTHORIZED in this Pair
Pair<Integer, ObjectMap> ret = buildResponse( unwrap( ex));
ResponseBuilder rb = Response.status( ret.left()).entity( ret.right()).type( "application/json");
if( ret.left() == UNAUTHORIZED.getStatusCode())
return rb.header( HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"YOUR SERVICE NAME\"").build();
else
return rb.build();
}
The important part is setting the response header if the user is not logged in, that makes the browser display the HTTP Basic Login Dialog.
I want to add user authentication to my restful api that I have created using the Java based Play! framework.
I currently have the Web based (browser accessed) app secured using the 'secure module' Details here: http://www.playframework.org/documentation/1.1/secure
Can I use the same module for authentication for when the restful apis are called directly via http requests?
If not, I would appreciate some pointers to tutorials/module for integrating another auth method (hopefully one that can apply to both web app access from browser and also http api access).
PS It would be nice to avoid doing HTTPS and digest if possible.
If you are already using a username/password mechanism adding http basic authentication for your API calls should not be difficult. You can create an interceptor that does something like:
public class ApiInterceptor extends Controller
{
#Before
static void checkAccess() {
if ( request.user == null || request.password == null) {
unauthorized();
}
boolean canAccess = .... ;// check user and password here
if ( !canAccess ) {
unauthorized();
}
}
}
But this means that you need to use SSL since the username and password go in clear text over http.
Context
I have a J2EE application running on a JBoss 4.2.3 application server. The application is reachable through a web interface. The authentication is done with basic authentication. Inside of the EJBs I ask the security context of the bean for the principal (the name of the logged in user) and do some authorization checks if this user is allowed to access this method of the EJB. The EJBs life inside a different ear than the servlets handling the web frontend, so I can't access the spring application context directly.
Required change
I want to switch to Spring Security for handling the user login.
Question
How can I propagate the spring login information to the JBoss security context so I can still use my EJBs without having to rewrite them?
Ideas and links
I already found a page talking about "Propagating Identity from Spring Security to the EJB Layer", but unfortunatelly it refers to an older version of Spring Security (Acegi) and I'm not familiar enough with Spring Security to make this work with the actual version (3.0.2).
Here is something that looks similar using WebLogic.
If you properly configure spring-security (filter in filter chain, security-context.xml),
you may use annotation #Secured, to restrict users with needed user roles. You may use this annotation on class level or/and method level.
If you need to know all authorization info about current user, you may use this helper (i wrote this for my webapp, but it maybe useful for other. MyUserDetails is a service bean, the spring-security's UserDetail descendant.):
public class LoginHelper {
/**
* #return user object if user is authenticated and null if is not
*/
public static User getUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
Object principal = authentication.getPrincipal();
if (principal instanceof MyUserDetails) {
return ((MyUserDetails) principal).getUser();
}
}
return null;
}
/**
* Check for authenticated user
*
* #return true if user is authenticated and false if is not
*/
public static boolean isAuthenticated() {
final User user = getUser();
return user != null;
}
}
I have the same issue, and it would be great if someone could think of a better way to integrate Spring Security and a Java EE application with EJBs.
I think you can annotate your classes with your own annotations such as #MyAnnotation("ADMIN"). And then create an interceptor to manually check the beforementioned "LoginHelper" to get the users's privilege and compare with the method's annotation attributes. And throw an exception when the Names don't match.