HttpServletRequest.getRemoteUser() vs HttpServletRequest.getUserPrincipal().getName() - java

These two seem to be doing the same things. Can anyone explain the main difference between the two? When would you use one vs the other?
HttpServletRequest.getRemoteUser()
HttpServletRequest.getUserPrincipal().getName()

A Principal represents someone who could potentially authenticate with your application. The Principal's name depends on the authentication method used:
a username such as "fred" (in the case of HTTP Basic authentication)
a Distinguished Name such as "CN=bob,O=myorg" (in the case of X.509 client certificates - in which case a X500Principal may be returned)
getRemoteUser() returns "the login of the user" which, in the case of HTTP Basic authentication, will also be the username; it doesn't map cleanly in the X.509 client certificate case though, since the user doesn't enter a "login" as such - in the example above, we could use the Distinguished Name or simply the CN, "bob".
The Javadocs state that "whether the user name is sent with each subsequent request depends on the browser and type of authentication", suggesting that getRemoteUser() was originally meant to provide data only for requests in which a username was entered. This, however, would result in it returning null for the majority of requests when cookie-based auth is in use - not too helpful!
In reality, getRemoteUser() often just calls getUserPrincipal().getName(); verified in Tomcat 6 and Jetty 6/7.

The getUserPrincipal() method returns an object of some class derived from the Principal interface, which is an abstraction of the entity that is the "user" responsible for the request. From it you get an actual object that, depending on the implementing class, you can use to get all sorts of information about that user/identity. One of those properties is the string-representation of the name of the user/identity, which you obtain by calling getName().
getRemoteUser() is really just a shortcut to getting that string-representation. You don't have access to any other methods implemented by the implementing class, not do you have access to the object itself, just the string-representation of the name.
For most use-cases that I am familiar with, that string-representation is what you want; I believe this is why getRemoteUser() exists - it's a common case so there's an easy/quick way to get access to it without actually getting a reference to an implementing class object.

A bit related issue:
People converting older IBM Portlet API code to JSR168 one had to change PortletRequest to HttpServletRequest in some method parameters, but then from WPS6.1 and up they can't cast that to PortletRequest (it doesn't implement the respective interface anymore as it seems) and if they call "getRemoteUser" directly on the HttpServletRequest they get back null (some say a workarround is to enable application security option in WAS [WebSphere Application Server], others say more security-related markup is needed in web.xml)
A workarround seems to be to use PUMA, but of course that is IBM WebSphere specific. Probably at other Portlet Containers there are other vendor-specific workarrounds if one finds that getRemoteUser always returns null (judging from other replies then getUserPrincipal().getName() also returns null if getRemoteUser is implemented as just a shortcut to that one).
BTW, the PUMA code I mention above is here, since it's a bit hard to find what works in WPS6.1+:
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.um.*;
import com.ibm.portal.um.exceptions.PumaException;
import com.ibm.portal.puma.User;
//...
public String getCurrentUser(){
try {
Context ctx = new InitialContext();
Name myjndiname = new CompositeName(PumaHome.JNDI_NAME);
PumaHome myHome = (PumaHome) ctx.lookup(myjndiname);
if (myHome!=null) {
PumaProfile pumaProfile = myHome.getProfile();
com.ibm.portal.um.User user = (com.ibm.portal.um.User)pumaProfile.getCurrentUser();
List attributes = new ArrayList();
attributes.add("uid");
Map userAttributes = pumaProfile.getAttributes(user,attributes);
return (String) userAttributes.get("uid");
}
}

Related

Vaadin UI - cannot use static fields for every client

I'm creating a web app.
I have a MyUI that extends UI.
public class MyUI extends UI {
public static Authentication AUTH;
#Override
protected void init(VaadinRequest vaadinRequest) {
AUTH = new Authentication();
updateContent();
}
//other methods
}
In Authentication() I have the user logged. When I do the logout, that user is set to null.
I noticed that when I access to the server from two device, so when I should have two connection to the server, when someone do the logout, the other one is logged out too.
In Authentication class there is this method:
public void doLogout() {
System.out.println("User: " + this.user.getMail() + " has logged out.");
this.user = null;
}
I get error in user.getMail() because the user is already set to null, when I try to do the logout from the other account.
Is com.vaadin.ui.UI unique? How can I handle different connections in Vaadin?
Java, in general
Basic Java here, nothing to do with Vaadin…
The keyword static means one value per class, otherwise known as a “class variable”, more generally known as a “global variable”. Not object-oriented. Generally speaking, you should minimize your use of static.
Omitting that keyword means “one value per instance of this class”, an instance variable also known as member variables. This is object-oriented.
I suggest you learn more of the basics of Java before embarking on a Vaadin project. And learn the basics of how Java Servlet technology works, perhaps reading the Head First book on Servlet published by O’Reilly (now outdated, but basics are the same). You also need to learn about advanced topics such as threading and concurrency issues as a Servlet environment such as Vaadin is inherently multi-threaded. Eventually, read the book Java Concurrency In Practice by Goetz.
Vaadin specifically
To store values per user of a Vaadin app, use session attributes. This is a key-value store where you insert and retrieve a value by specifying a key, the name of the "attribute". The session is automatically instantiated for you when the user first connects, as part of the Java Servlet technology.
Alternatively, you can store values per user on that UI class as instance variables. Each Vaadin user starts with a UI instance when first connecting. But beware: you can open multiple web browser tabs/windows in a Vaadin 8 app, each having their own UI instance. So to share data between those multiple UI objects, use the session attributes.
Note that while every Vaadin app has at least one UI subclass defined, you can define additional UI subclasses as well, for those additional browser tabs/windows mentioned above to show different content.
Maybe instead of static variable you should use here session attribute (updated to be more generic):
UI.getCurrent().getSession().setAttribute("AUTH", AUTH);
Authentication auth2 = UI.getCurrent().getSession().getAttribute("AUTH");
So use VaadinSession to store session specific data.

Best factory pattern for delivering app data object based on application type in http header

I have a business with multiple applications using my webservice resource. I have a web service resource that looks in a http header for the application ID. This tell the server which application is requesting data. My goal is to deliver to my web application developers a method they can call to retrieve all the application specific settings via the application ID.
Given an applicationID i can specify device type, properties file for that app, and whether GCM,APNS or Microsoft Push Notification, etc. So each applicationID has distinct properties basically.
I want the developer to be able to call for this object like this (or similar):
ApplicationData appData = ApplicationDataFactory.getCurrentApplicationData();
and the factory would look something like this:
class ApplicationDataFactory
{
public static ApplicationData getCurrentApplicationData()
{
//notice how im not passing in criteria here, im getting it from the request so call doens't have to know
String criteria = Request.getHTTPHeaderInfo("applicationID");
if ( criteria.equals("Android") )
return new Android();
else if ( criteria.equals("Android-germany") )
return new Android_germany();
else if ( criteria.equals("ios_germany") )
return new ios_germany();
else if ( criteria.equals("ios"))
return new ios();
else if ( criteria.equals("windows") )
return new windows();
return null;//or throw exception
}
}
so Android, ios, and windows objects all extend off ApplicationData class clearly.
So for example the Android.java object would look like this:
class Android extends ApplicationData{
#override
public String getType(){
return "Android"
}
#override
public Properties getProperties{
return system.getProperties("android.properties");
}
}
and the Android-germany and ios-germany will have common data since there both from germany.
First, i dont like that im specifying the criteria inside the factory and also can anyone help me
with a good design pattern i can use to achieve this ? Remember, in the end i want to be able to have the developer call only ApplicationDataFactory.getCurrentApplicationData(); (or something similar) and the correct application info will be sent referenced. I dont have to use a factory here either its just the first thing i thought of.
So your problem is with the fact that the logic for the criteria is within the factory method. Meanwhile, you don't want the user to provide the criteria as an parameter to the factor method.
First of all, I don't like the idea of having a static Request class. A request should be an object that contains information about the current request. I have a suspicion that your code may be prone to race conditions, once you have many concurrent requests (how do you know which request is which?). So as a starting point, I would refactor the Request class so that you work with instances of Request.
I think, the clearest approach would be that you pass in applicationID as a parameter. This makes testability trivial and the code becomes very obvious, too. You take an input and produce the output based on the input. You could pass the Request instead of the applicationID and let the factory handle the retrieval of the applicationID from the request (as you are doing now).
If you think the Request -> applicationID logic should not be part of the factory, you can create another class, such as ApplicationIDResolver which translates a Request to an applicationID. From then on ApplicationDataFactory would be used through an instance and the ApplicationIDResolver would be a constructor parameter. (I think, this is an overkill.). Another option is to add a getApplicationID() method to the Request class.
If you use a dependency injection framework, it may take care of object life cycles/scopes automatically for you, so the ApplicationData could be a request-scoped object and you could tell your dependency injection framework to instantiate ApplicationData objects based on requests and inject them into the classes where they get used.
Better to use for this purposes enum which implements ApplicationData interface and define each entry. You can resolve proper by valueOf() from enum.

Best practice to inform client about the itemId newly created

I own a DDD/CQRS application.
My question concerns the handling of an item creation through POST (Rest).
CQRS (based on CQS principle) promotes that commands should never return a value.
Queries are there for that.
So I wonder how to handle the use case of Item creation.
Here's my current command handler pattern (light for the sample (no interfaces etc.)):
#Service
#Transactional
public CreateItem {
public void handle(CreateItemCommand command) {
Customer customer = customerRepository.findById(command.customerId);
ItemId generatedItemId = itemRepository.nextIdentity(); //generating the GUID
customer.createItem(generatedItemId, .....);
}
}
By reading this article, an easy method would be to declare an output property in the command, populated at the end of the handle method like this:
public void handle(CreateItemCommand command) {
Customer customer = customerRepository.findById(command.customerId);
ItemId generatedItemId = itemRepository.nextIdentity(); //generating the GUID
customer.createItem(generatedItemId, .....);
command.itemId = generatedItemId; //populating the output property
}
However, I see one drawback with this approach:
- A command, in theory, is meant to be immutable.
This itemId would then be sent thanks to the calling controller (webapp) through Location Header with the status 201 or 202 (depending if I expect async or not).
An other solution would be to let the controller initialize the GUID by accessing the repository itself, thus letting the command immutable:
//in my controller:
ItemId generatedItemId = itemRepository.nextIdentity(); //controller generating the GUID
createItem.handle(command);
// setting here the location header (201-202) containing the URL to the newly created item with the using the previous itemId.
Drawback: Controller (adapter layer) accessing directly the repository ..., that is too low-level IMO.
My extreme client being a Javascript application, I might have another solution to let the Javascript itself generate a GUID, and feed CreateItemCommand with it before sending the whole command to server.
Advantage: No more issues about potential violation of CQ(R)S guidelines.
Drawback: Should check the validity of the passed id at server side. Although there would have an index unique on this preventing an unexpected insertion in database.
What is the best (or just a good) strategy to handle this?
I am the developer of a CRM application based on the CQRS pattern. I tend to see commands as immutable. The team decided early on, that all IDs are generated on the client to have immutable commands. This is perfectly ok, as we are using UUIDs. So we are quite confident, that the IDs are valid and there are no ID collisions. We went well with that approach up to this point - I can definitely recommend this. In that scenario the client just knows the IDs.
Sometimes it happens though - especially in manual testing - that a create command is dispatched twice with the same ID. In that case the addition of events in the event store fails (we use event sourcing) with a duplicate key exception. The exception is passed to the controller. In fact we do return results from command executions with a call back, even though it's just "everything ok" most of the time - so no exception thrown. Also command validation is done this way. We do this using a command bus concept.
I would recommend taking a look at the Axon framework. We use it, it provides the common building blocks, and it just works. Maybe you can get some inspirations from that!

Getting execution method annotations in a interceptor

I have some actions that requires a specific user permission to be accessed, so I created a method annotation #RequiredPermission and a interceptor to verify if the method that is going to be executed have or not the annotation and if it have verify if the logged user have the permission.
The problem is that I don't know how to get this information from ActionInvocation and neither from ActionContext.
I'm sure that should be one way to do it, cause if not I'd say its probably a not good framework to work with.
Any tip?
The information you need is contained in the ActionProxy, available via ActionInvocation.getProxy().
Once you have the proxy, you have access to the action itself (from the ActionInvocation) and the method name (ActionProxy.getMethod()) as a string.
From then on out it's normal Java reflection.
Method method = action.getClass().getDeclaredMethod(actionmethod);
RequiredPermission permission = method.getAnnotation(RequiredPermission.class);
if (sessionUser.inRoles(permission.getRoles()) {
return invocation.invoke();
}
return Constants.LOGIN_REQUIRED_RESULT;
Or however you want to handle the actual logic.

How to preserve object identity across different JVMs

To be specific let me illustrate the question with Spring http-remoting example.
Suppose we have such implementation of a simple interface:
public SearchServiceImpl implements SearchService {
public SearchJdo processSearch(SearchJdo search) {
search.name = "a funky name";
return search;
}
}
SearchJdo is itself a simple POJO.
Now when we call the method from a client through http-remoting (Spring's mechanism of calling remote objects much like EJB that uses serialization) we'll get:
public class HTTPClient {
public static void main(final String[] arguments) {
final ApplicationContext context = new ClassPathXmlApplicationContext(
"spring-http-client-config.xml");
final SearchService searchService =
(SearchService) context.getBean("searchService");
SearchJdo search = new SearchJdo();
search.name = "myName";
// this method actually returns the same object it gets as an argument
SearchJdo search2 = searchService.processSearch(search);
System.out.println(search == search2); // prints "false"
}
}
The problem is that the search objects are different because of serializaton although from logical prospective they are the same.
The question is whether there are some technique that allows to support or emulate object identity across VMs.
You said it - object identity is different from logical equality.
object identity is compared with ==
logical equality is compared with .equals(..)
So override the equals() method and all will be fine. Remember to override hashCode() based on the same field(s) as well. Use your IDE to generate these 2 methods for you.
(Teracotta VM clustering allows sharing objects between VMs, but that doesn't fit your case.)
IMHO attempting to preserve object identity equality across VMs is a losing proposition.
To the best of my knowledge the language specification does not require a VM to support that, so you would be limited in where you can pull off if you truly want to be portable.
May I ask why you don't just use some unique ID that you supply yourself? Java GUIDs, while expensive, are serializable.
I did this once, but I'm not quite sure if this is a right approach:
Every user had a username, session id, roles, and a login date attached to a user object. Every time I logged into a VM the system would load a User object into memory; I would also return the user object to the application.
If I needed to execute an action within the application server, then I would send the user object as an argument. If the VM had the User loaded with the same session ID then it would use the object stored in the VM to know the assigned roles. Otherwise, the application would then be capable of changing the roles in the user and it wouldn't be secure.
If the application had to change the application server, then it sends the user object to the new server and the new server wouldn't be able to find the user within its records.
HERE IS THE SECRET: The session ID is created hashing the username, the login date and a secret password shared among all of the servers.
Once the new server finds that the session ID is coherent, then it would load the roles from the database as a reliable source of information.
Sorry if I couldn't write this before, but hope it helps for someone.

Categories

Resources