The application I work on must use a different Base URL for every user. Basically the user has his own server, and in the application he must specify the IP Address for his server in a Text Field so the application can start doing HTTP Requests to that server.
When I create the Retrofit instance it requires a Base URL, but there is now way I can access it from the UI, since the user has to enter the base URL manually from a Text Field.
As a workaround I just pass Google as the Base URL when I create the Retrofit instance and then use the #URL Annotation to pass the whole URL, but from what I know the #URL Annotation is limited to GET and POST Requests.
return new Retrofit.Builder()
.baseUrl("https://google.com")
.build();
Is There any better way to achieve this or should I stick to the #URL Annotation?
Thanks for your time!
you can add a parameters when calling that
getApiService(userBaseUrl : string){
....
....
return new Retrofit.Builder()
.baseUrl(userBaseUrl)
.build();
}
Related
I am currently developing an OAuth 2.0 resource server (REST API) with Spring Webflux.
I have Spring Security set up and I can successfully authenticate users with Spring's built-in principal class.
The problem:
The application needs to store additional information about the user as per requirement.
Users that access the API for the first time are not stored in the REST API's internal user database. Right now I have to check if the provided principal name (I have access to the respective OAuth UUID - the one stored in the authorization server) already exists in the application database.
I would like to avoid code duplication, where I would have to call a method that does exactly that on every endpoint
Here is what already works:
#GetMapping("/secure")
fun secureEndpoint(principal: Principal): ResponseEntity<Void> {
println(principal.name)
// here I would have to check if the user has already been
// created in the database
return ResponseEntity.ok().build()
}
As I said, the principals correct UUID is already being displayed.
What I am looking for is some kind of webfilter, that runs before every (authenticated) endpoint, and automatically creates the user, so I do not have to do it in the controller layer.
This is my Security configuration:
#Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
val cookieServerCsrfTokenRepository = CookieServerCsrfTokenRepository()
cookieServerCsrfTokenRepository.setCookieHttpOnly(false)
http.authorizeExchange()
.pathMatchers("/**").permitAll()
.pathMatchers("/secure/**").authenticated()
.and()
.oauth2ResourceServer()
.jwt()
http.csrf()
.csrfTokenRepository(cookieServerCsrfTokenRepository)
return http.build()
}
I would greatly appreciate any help!
I am using basic authentication mechanism in my Dropwizard application, where I am capturing logged in user details, something like this:
#POST
#Timed
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/pdf")
#Path("/")
#RolesAllowed("user,admin")
public Response function(#Auth User user) throws Exception {
//some logic around here
}
Now for auditing purposes, I want this user information to be passed at each layer of my application, I mean in services, DAOs, ExceptionMappers etc and I don't want to pass it as function parameter everywhere as it looks clumsy and also has maintainability overhead. so my question is, is there any way by which we can set some global configuration per REST call or user session and can fetch it anywhere I want?
I have been a Ruby user and in that we were able to do something like this:
Thread.current[:user] = user
which which accessible throughout per user session.
One way to achieve this is by using ThreadLocal of Java wherein you can set the User object and it will be available to that particular executor thread.
Add the following to your resource class.
private static ThreadLocal<User> localUser = new InheritableThreadLocal<>();
public static ShortenerServiceUser getUser() {
return localUser.get();
}
Whennever your function() method is invoked, you just need to set the User object into the ThreadLocal variable.
localUser.set(user);
Now, whenever you need to access the User object from the current thread context, all you need to do is as follows
User localUser = YourResource.getUser();
You can clear the User object from the context by using the ThreadLocal.remove() method.
I need to access the user's password in a Jetty application after authentication, and can't figure out how.
I am migrating a set of web pages away from basic authentication in an embedded Jetty servlet application. I cannot, however, completely remove basic authentication from all of the services that these pages call, so I need to forward the user credentials in some cases, which means storing and later retrieving the user's password.
I introduced forms authentication to the root context via the standard markup in web.xml, which works fine but I can find no way of getting the user credentials programatically. As far as I can tell there is no way to place a Filter on j_security_check to intercept and store the form parameters in the session state. Jetty provides all the user credentials in the session state but this is in a container-specific key and although the application is currently tied to Jetty I would strongly prefer a container-agnostic solution. Here are some specific questions that I've tried to formulate after going down a number of seemingly dead-end streets:
How can I obtain the user's password after login? Even if I moved the services away from basic authentication I would still need to perform some secondary action such as obtaining a token, in which case I would still need their credentials under my control for a brief period.
Assuming I can't obtain the user's password directly, perhaps I can leverage something in the container to store the credentials. I can implement my own LoginService that wraps the actual implementation, but that class does not have access to the HttpSession or Request objects. Where is the proper place to do this?
If I need to implement a custom login solution, I'm not quite sure where to start...the FormAuthenticator has a lot of complicated session state management that I would like to preserve and not reproduce willy-nilly, and I would still prefer to defer to the container standard as much as possible. Is there some standard method for extending or overriding the j_security_check logic?
I finally found one solution, for anyone else attempting similar - and I've found quite a few other posts from confused devs, and some badly hacked together workarounds. I believe this one is correct, although you must do the URL filtering yourself and it leaves open the question as to why this is possible, if indeed j_security_check should be exempt from this type of interception for security reasons, as is claimed many places online. Perhaps I am merely exploiting an unknown gap in the Jetty security measures, so I will leave this question open for a while to see if there is a more robust or explicit solution.
ServletRequestListener allows you to latch onto the j_security_check post request before it is fully initialized. There you can get both the form parameters and the session object. So in the end it was just a matter of exhausting every possible servlet-related class in Jetty until I found one that would give me access to the j_security_check request. Some code:
public class PreAuthenticationRequestListener implements ServletRequestListener {
public static final String USERNAME_KEY = "USERNAME";
public static final String PASSWORD_KEY = "PASSWORD";
#Override
public void requestDestroyed(ServletRequestEvent sre) {
}
#Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
if (request.getRequestURI().contains("j_security_check")) {
final String username = request.getParameter("j_username");
final String password = request.getParameter("j_password");
HttpSession session = request.getSession();
session.setAttribute(USERNAME_KEY, username);
session.setAttribute(PASSWORD_KEY, password);
}
}
}
I am building an app where I use Scribe for all my oauth needs. I create a service API class overriding DefaultApi20 with my end points for authorization and token URLs.
However for Shopify, the authorization URL is dependent on another parameter (Eg: shop name) where the authorization url needs shopname as subdomain. How do I send parameters for this?
I can do the oauth manually constructing the auth url and token but I am looking for a better way to construct sending custom parameters.
Thanks.
We had a similar situation where a variable on the API had to set differently for different users. We did the following:
-Created a custom serviceImpl which extended OAuth10aServiceImpl (may be OAuth20ServiceImpl in your case).
-gave it a method to set the variable on it's api class
-after service is created by your ServiceBuilder lookup the appropriate value and call the setter method of the service.
-continue with normal OAUth token flow
Note that you also need to let the API know to use the custom service class, for example:
#Override
OAuthService createService(OAuthConfig config)
{
return new CustomServiceImpl(this,config)
}
Hope that helps
I've built my first grails application. My URL mappings are what the default application provides:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
Senario
I have a controller called ColorController with actions save and list. It simply does something like this:
def save () {
def colorInstance = new Color(params)
colorInstance.save(flush: true)
}
def list () {
[colorList: Color.list, colorTotal: Color.count()]
}
I would like to build a simple API for these actions.
The save action should accept parameters as JSON and provide a successful message if the records save.
The list action should provide the list as JSON
Questions
Should I make a separate URL mapping for api? (e.g. http://<domain>/<app>/rest/controller/action)
Should I be making a separate controller for my API's
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that?
If I use the same controller, how can I modify these simple actions to do what I need.
Before even looking below for my opinion/answers I would suggest to visit this SO Question for the basic understanding of RESTful WS in Grails.
Opinions:
"The save action should accept parameters as JSON and provide a successful message if the records save" - Save is mapped to POST RESTful. Instead of binding a JSON body to params it is bound to the request. In order to access the JSON object you just need to use request.JSON in the action method.
request.JSON instanceof JSONObject
"The list action should provide the list as JSON" - list() action is mapped to a GET Request and you can render the map as JSON in the list() as below
//Controller list()
import grails.converter.JSON
def list () {
[colorList: Color.list, colorTotal: Color.count()] as JSON
}
Answers to Questions:-
Should I make a separate URL mapping for api?
Abiding by the basics of REST, the client should only access the resource (Color in this case) and should not bother about the underlying controller or action. The server side logic should be abstracted from the client. URL Mapping is what the client would use to as form of request. I would have something like this in my url mapping for Color Resource.
/color/$id?(resource: "color")
or
/color/$id?(controller: 'color'){
action = [GET: "list", POST: "save"]
}
Should I be making a separate controller for my API's? - Depends on the way the App is designed. You also can have the above controller as the API. For example, currently I am working on a grails app which used AngularJS in the front End which connects to the Grails APP RESTFully. In order to achieve I had a RestClientController which works as an API to Angular. The rationale behind having a REST api in the same app is that in future we can expose the underlying service to external clients other than the Angular client present in the app itself.
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that? - You can use Spring Security here as well. In my case I am using the plugin and I secure the controller by using the plugin's annotated component #Secured. I have custom OAuth enabled as well for authorization which interacts to the company wide LDAP and AD Groups.
If I use the same controller, how can I modify these simple actions to do what I need. - I think you would have got the answer to this question by now (after going through the SO question I mentioned above). Here is my opinion, controller actions can route to appropriate service classes which does the business implementations based on the request parameters.
For example,
//Action
def show(){
if(params.id){
colorService.getColor()
} else {
colorService.searchColor()
}
}
In the above example, the url mapping would be /color/123 or /color. In the former case, it will get the color and in the later it will search the colors