I am using AngularJS along with REST API on Java EE 7 backend.
The project is deployed on a Wildfly application server and I have some questions regrading securities:
To Encrypt/decrypt data I am using CryptoJS to encrypt and decrypt on server side ( Java ) but apparently we have to send the passphrase in clear, the cipher and salt are only encrypted.
My question is why the passphrase is clear text ? it should be secret and then encrypted as well no ?
For the REST API, what is the standard to use for Java EE 7, HTTP security header (basic-auth) ? Json Access token ? and how it really works, where to store user session/token, on a cookie ? I just want to know how to do it with Angular.
Maybe I can use the classic JAAS with form-based authentication and then having request.login() on server side to be authenticated then my EJB will be all protected by #Role.
What is the way to protect pages in AngularJS ? For the moment I am using the web.xml and putting the URL patterns, maybe there is a better way ?
I already found lot of examples like this:
AngularJs and Jboss and JAAS ( omnisecurity )
how to integrate angularjs and java jaas based authentication?
Some users mentions this:
* index.html page should contain token inside html to avoid CSRF
* token shouldn't be stored in a cookie storage
* Each request should be signed with header param
* Server should validate every request by passed header
* If cookie usage is a must you should validate referer in order to prevent CSRF
But there is not concrete example on how to implement this, especially the CSRF.
To Encrypt/decrypt data I am using CryptoJS to encrypt and decrypt on
server side ( Java ) but apparently we have to send the passphrase in
clear, the cipher and salt are only encrypted. My question is why the
passphrase is clear text ? it should be secret and then encrypted as
well no ?
As soon as you are sending a key (passphrase?) in clear - the encryption is useless.
To achieve reasonable client-server security, use the HTTPS. Simple, effective and much more secure. Generally it is a bad idea to encrypt on the web application side, as the user or a 'man-in-the-middle' can retrieve or modify the key and data.
The different case is end-to-end security, when the client encrypts, posts encrypted data and they are stored/processed as they are, with the encryption key available only to the user. If it's not the case and the service needs the data for further operations, the HTTPS is the way to go.
For the REST API, what is the standard to use for Java EE 7, HTTP security header (basic-auth) ? Json Access token ? and how it really
works, where to store user session/token, on a cookie ? I just want to
know how to do it with Angular.
Effectively you listed you options. This is your decision. Every option has its pros and cons. Basically - if you're talking about (REST) services, it shouldn't matter what technology is used.
For the REST services called directly from the browser I'd omit the basic authentication (otherwise user would get the pop-up authentication window)
You can use the JWT token (signed by the application secret, just add some expiration date), but then you cannot 'logout' the user, just wait until the token expires. The advantage is, that the token is 'self-sufficient' and you need not to worry about the session management. The client sends the JWT token in the Authorization HTTP header, you just decode it, validate and then you can assume the identity from the token.
Another option is a session token (cookie or sent as an Authorization header), where you need to manage the sessions (store the tokens, clear the token out on logout, ...). Using the app server session cookies makes your services unusable by other applications (still a question - do you want/need the services to be reusable by third parties), but you achieve built-in authorization (JAAS , Roles, ...).
Maybe I can use the classic JAAS with form-based authentication and
then having request.login() on server side to be authenticated then my
EJB will be all protected by #Role.
Indeed, this is a way how you authenticate and authorize the user and issue a token (jwt, cookie, other...).
What is the way to protect pages in AngularJS ? For the moment I am
using the web.xml and putting the URL patterns, maybe there is a
better way ?
The default web authorization should be ok.
Still - keep it simple. According to my experiences the static resources (web pages, images, scripts, css) should be static and it shouldn't really matter if they are publicly available. The important is the execution (operations, data, ...) are exposed as the services and that's the point where you do proper authentication and authorization.
Have fun
Related
I have a Java Spring driven REST API server connecting with PostgreSQL database and a Spring Web Server in Java that is serving content from the REST API to the client using JavaScript (now browsers, but in the future also mobile apps).
I've read a number of articles and topics how one can secure a REST API, but I haven't been able to make a final decision yet. I don't want to have Basic Authorization, because it doesn't make sense as I would need to store credentials in JavaScript that can be easily accessed and read by anyone entering the webpage and developer console. I'd like not to show any credentials to the end user so I can't keep them on the client's side.
I've read a lot about JWT and almost decided to implement it, but I've heard it has some drawbacks and haven't been so sure since then if it's the option I would like to choose. I know there is also oAuth 1.0 or oAuth 2.0 but I don't know if I want to have something this complicated. I would also like to store hashed user credentials in my own database in order not to be depended to any other credential providers like social media or Google.
Now I'm making another layer on my web server as a proxy hoping that it will allow me to authenticate user on this proxy level using Spring Security and having some kind or cookies or something to authenticate, but I'm not so sure if its doable this way and it increases the respond time, adds complexity and needs me to write controller methods for these endpoints. My architecture now is of the following:
Client (browser) -> Webserver -> REST API server -> db
I've also denied all external connections and allowed only localhost access to REST API on tomcat level so that I'd have to implement the security level only on the web server allowing free information transit between the webserver and REST API as it is not reachable anyway.
Web server and REST API are on the same server running as Tomcat instances.
I'm also not so sure if this kind of architecture will allow me to authenticate mobile app clients through the web server.
I would be very grateful for any piece of advice you would have for me in this matter. I'm not so experienced in security, so I'm a bit lost what I should do. Does this kind of architecture any sense or should I simply ask REST API directly from any type of clients, be it a webpage or a mobile app from different IPs and secure Rest API only? And if I want to secure some subpages of my webpage or parts of mobile app should that be an completely other layer?
Thank you for your help.
You have already gone through OAuth, JWT tokens etc. If you don't want to use them,then you can create your own token based authentication system.(say 'TokenHandler').
How this TokenHandler will work ?
TokenHandler will be like a gateway server i.e your every REST API request will route through this server application. So you will address your confusion of mobile and web application call with a authToken in header. Main responsibility of this server applciation is to accept the token and validate against the database where all token details are maintain. This DB will have information regarding timestamp when token was last used to validate, to decide your validation rule .
How Token will get generated ?
Token can be any random 64 digit alphanumeric string and will be generated and updated in DB during every single login activity. Login webservice returns this token in response body.
What can be rules for validation ?
It can be depending on your business logic. I preferred to keep active session window of 15 mins. Means if you access the webservice you will get active window of 15 more minutes. If you didn't access any service for 15 consecutive minutes then from 16th Minute you will need to login again to access further calls. This part can change according to requirements.
How client side will handle this ?
Client side will store this token and pass this token with every request call. Token Handler will validate and redirects it's request to the application server . So your one token handler can be used to server authentication of multiple applcation servers. This you can achieve by application end point identifer.
I will like to discuss further if you have any questions or suggestions .
Use API Gateway Architecture Pattern for your use case -
http://microservices.io/patterns/apigateway.html .
The API Gateway (The webserver in your question) can act as single entry point for all desktop/mobile clients. You can use either session cookies or jwts to authenticate clients at gateway.
With respect to authentication between gateway and micro services, and between micro services, i would suggest mutual ssl - https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication. If you are using spring boot, this might help - http://www.opencodez.com/java/implement-2-way-authentication-using-ssl.htm
The problem with IP white-listing approach is that - it's not well suitable for cloud architecture as the IPs might change with every server reboot. Even if you are using dedicated IPs, you should be careful to secure the communication with SSL/TLS, else attackers can easily sniff your traffic.
I'm trying to create RestApi first time. Looking for assistance after reading text present online.
My requirement is, I want to create an rest api which will be having username and password. Password will be in encrypted format. So when this api client will request to a web server, that password will be decrypted first on server side and then if the user name and password authenticates then it will send back a temporary token with expiry date. Then again that token will be used in rest api to request data from the web server in xml format.
How can we achieve this ?
And I also want to understand if we encrypt a password in client server then how its get decrypts on web server side. Is the same instance travels from client to web server side while making request ?
Second, The data which I'm trying to consume from web server are the email ids of users which registers on website. My question, If user is getting registered on website then website must be storing those email ids somewhere like in database right ? And my restApi will be accessing the code on web-server side which is responsible to get email ids from database in xml format. Is my understanding correct ?
First, don't concern yourself directly with encrypting details client-side and decrypting them server-side. If you are using TLS/HTTPS (which you should be) then all is well, everything is already encrypted.
The token generation is slightly more difficult but still easy enough. A commonly used and simple to implement method is to use JWT tokens. The general idea is that you create a JSON object like the following:
{ "userID": "FC5A47CC", "expiry": "12/10/2017" }
And then run it through an HMAC using a key only your server knows. You append the result of the HMAC to the JSON object using base64 encoding and then send this to your client after they have logged in.
Using this method, authentication is very fast, as your web server won't need to make any requests to your database server to determine if the token is valid. You can read more about JWT here. I've answered a similar question in more detail here.
As your question asks, these userIDs will obviously need to be stored in your database.
Seems like you want client app to consume resources on behalf of user. I propose OAuth 2.0, which provides mechanism, which you have described to access protected resources without storing passwords. Client app requests a username and password from the user (for example by using a login form) and then send that credentials to the server. Upon receipt and validation server returns token to the client. Client stores token locally and discards username and password. All subsequent request are authorized by token, which can be accomplished using a custom HTTP header, for example X-Auth-Token. Server can optionally provide a refresh token along with the access token, which is used by client to obtain new access token, once current expires. HTTPS/SSL technology is required by OAuth 2.0, so data over wire will be encrypted.
There are 4 roles defined by OAuth 2.0 :
1) Authorization Server — does identity verification and grants token to the client app.
2) Resource Server — Server which hosts actual protected user resource.
3) Resource Owner — User willing to provide access to his protected resource.
4) Client — application that gets access to a user’s resources.
You can use Spring Security OAuth framework to implement this requirement.
I googled and I only found documents on how to create a sign in button on your android application, or how to create a sign in button on your web application.
My scenario is that the android application retrieves information from my website using get/post http requests and getting json data.
I have a working android sign in button on my android application.
the question is that when i want to retrieve information from my website using get/post request, what information should I send in order for the website to know which user is retrieving that information and that the user is logged in ?
I know that I can't just send the google user id because that's not secured and easly hacked. I'm guessing I need to send some kind of access token and on the web site to parse that access token in order to know which user it is. but what exactly do I need to do?
My client side is PHP with ZendFramework 2 and ZfcUser with scn-social-auth for google login.
any information regarding the issue would be greatly appreciated.
thanks
In my previous staff project, i've implemented our Api modules for Zend Framework (it was version 1 but it is the same for version 2).
Basically, i've implemented the OAuth protocol 1.0 ( rfc at https://www.rfc-editor.org/rfc/rfc5849 ), that is a really strong way to improve the connection security between a generic client ( Android, iOS, Mac OSX, Windows Phone ,... ) and web service.
Shortly it consits into enforce the https protocol ( i hope you are working in httpS ) signing all the client get/post requests with the base OAuth parameters ( such as oauth_version,oauth_token,... all explained in rfc) in order to avoid MITM and proxy to alter the request. Using this method i've make a specific table into which store Request and Access Tokens.
So:
Client has consumer key and consumer secret
Server has same consumer key and consumer secret
OAuth will use that keypair to authenticate the connection
Client obtain "Request Token" from server
Client perform common username and password login through OAuth workflow to the server
Client obtain Access Token ( if login with success ) that will be stored on the token db table, and wil be used to check if that user on that device is logged in and so authorized to use the service (so you'll probably need a device guid also )
You can find good guidelines and good github projects on how implement your own OAuth protocol ( see also service like Dropbox or Twitter developer sections, about how they use OAuth for their service ). Consider that you can obviously customize your OAuth protocol once implemented, with additional controls and tokens ( i've used AES-256 encryption and RSA 2048 bit for some custom tokens, and also to encrypt username and password for the login with a received key combination in the previous step expected by OAuth workflow ).
In the end, you can connect the clients to your web service with your custom tokens so, once authenticated, you make you web service to interact with google service and return information to client always through your website
Hope it helps
If the user login server is the same with the one that you want to retrieve information,you can use the sessionId as the token.
1.After authentication,server store userId in the session
2.Server use session_id() to get sessionId ,return it to android client
3.add ?PHPSESSID=sessionId param to the android client http request.
4.Server get userId from the session
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.
You can add GET parameter PHPSESSID to any requested url.
$manager = \Zend\Session\Container::getDefaultManager();
//$manager = new \Zend\Session\SessionManager();
$PHPSESSID = $manager->getId();
I am developing a web service using Spring framework for Java and deploy on JBoss AS. This web service needs authentication and authorization and security solution so that some method user A can execute and some other user B can execute. At client side, there will be an application calling to the web service and people may log in using either user account A or B.
I have been digging out the Internet, searching for web service authentication, researching on WS-Security but all that I can see is using WS-Security. WS-Security generally supplies 4 kinds of authentication:
UsernameToken
X.509 Token
SAML Token
Kerberos Token
But all those things are usually pre-configured and I find no example that suggest I should provide login/logout methods in the web service (by using stateful web service). Note that in case we use login methods then there are security risks even if the underlying is SSL transport.
So my question is:
What should I do to satisfy my requirements?
If using UsernameToken or Kerberos Token ... and we provide some privileges per user, i.e authorization, then for each incoming request, we must get the user information and get all its privileges. This process seems take time and decrease performance of the system. Do you agree? So I guess this is not recommended?
I would thank you so much for any response and will vote for any reasonable answer.
Your scenario mirrors that of EBay Trading API's.
Basically, it works as follow.
Provide a intial WS call (Ebay case: FetchToken) which confirms user's identity and return back authorization key (unique key for each logged in user). Store the authorization key along with user profile information in a cache/distributed cache .
Any subsequent call required client to pass the authorization key along with the data for the call. You will use the authorization key to get user profile information.
Provide the log out WS call. This invalidates the authorization key.
All the WS invocations should happen over SSL for security.
If your service is point to point, ssl is enough. Mutual ssl (Mutual_authentication) is widely used for client authN and authZ.
If you concert about performance of system, looking at SAML. SAML is a signed XML document that contains authN and authZ for client, that means you do not need to loop up on the server for client authN and authZ.
What is the best way to do authentication and authorization in web services?
I am developing a set of web services, requiring role based access control.
Using metro - SOAP, simple java without EJBs.
I want to Authenticate the user just one time, using username and
password, to be matched against a data base. In the subsequent calls.
I would like to use some kind of session management. Could be some
session id, retrieved to the client at login, to be presented in all
calls.
So Far:
Read authentication using a database - but I want application level validation;
Read application authentication with jax-ws - but i don't want to do the authentication mechanism every time;
I think I can use a SOAP Handler, to intercept all the messages, and do the authorization control in the hander, using some session identifier token, that comes with the message, that can be matched against an identifier saved in the data base, in the login web method.
EDIT:
I still have some questions:
How to know the name of the web method being called?
What kind of token should I use?
How to pass this token between calls?
EDIT 2
Because of #ag112 answer:
I'm using Glassfish.
I use WS-Policy and WS-Security to encrypt and sign the messages. Using Mutual Certificate Authentication. I would like to complement this message level security between applications, with the authentication and authorization for the users also in message level.
I am just developing the services, and I don't know almost nothing the clients, just that they could be created in different languages.
At this point I think the most important thing is to do what ever I need to do to authenticate and authentication the users, I the most easy way to be implemented for the client applications.
#Luis: Here are my inputs.
Well exact solution for your problem depends upon kind of web service clients you expect, do you have control over web service client system, your app server etc.....but assuming you don't have any control over web service client, for you it is just a SOAP message over HTTP transport, here is probable solution.
You can of course performs session management & authentication at message level or transport level. It means either you can have session token and auth token information in SOAP message or you can use standard HTTP Session and HTTP authentication mechanism.
Of course transport level solution is much simpler and industry wide standard in case if transport layer is HTTP. For message level, ws specifications like ws-security can be used.
Your each web service request is simple HTTP GET/POST identified by a unique HTTP URI.
Typically in jax-ws metro environment, WSServlet is one which entry servlet for any web service call and which eventually delegates the call to right service provider implementation class. Since you application is going to be deployed in web server, you can exploit all session and authentication facilities provided by J2ee web container.
Since you are looking for role-based access control, I would use standard <web-resource-collection> in web.xml to specify which role you would like to have in case of particular HTTP URI. You can use standard JAAS login module which can do authentication and populates the JAAS subject with role. If user name/password are provided in SOAP XML, JAAS login module can also search/parse SOAP XML to retrieve those information. JAAS/app server will automatically create auth token and store it as cookie so that each subsequent request need not to go through authentication process again. This is all J2ee standard. You can find plenty of help on internet on this. Please let me know your app server so that I can provide you additional details.
If you still want to use SOAP message level session management, authentication & authorization process, then to provide you more details, may I know more details about your client side.
EDIT1:
Well based on your further inputs, here is my more thoughts:
Message security namely encryption and signature needs to happen each message travels between server and client. where as message authentication- you intend to do once and give a session token/auth token to client for subsequent calls.
Question still remains: if you put a unique session Identifier in SOAP response of first time authentication, do you expect client to parse SOAP response XML and ensure that client should send you session identifier each time in subsequent SOAP requests.
OR
You want to keep session management transparent to client and for client it needs to send username/password token first time and subsequent calls need not require any username/password token. In this case you would need to rely on transport based session management for e.g. HTTP cookies
Now what is the best for you depends upon your use case. Can you tell me what is expected use case flow? how another system (web service client) makes more than one service call to your system? Is another system user driven/some background process? What is exact need that you want only first service call to go through authentication process not subsequent calls?
PS: Glassfish server provides a way of configuring message authentication provider which automatically enables/disables message level authentication.
EDIT2:
I understand you do not want to store user credentials in client app and web service server need those user credentials.
OAuth is open standard protocol which allows site A to access user's private data on site B. Ultimate idea is site A gets auth token which has specific expiry time. So Token containing encrypted from of user credentials or jsession id help you avoid need of re-authentication. You only need to decide where you want to keep token at client app side
You can keep token as cookie if transport is HTTP protocol.
Having said that ofcourse passing user credentials each time seems bit easier and straight forward.
You can also go for OpenEJB.
It used JAAS with WS-Security.
I hope the link is useful.
After all the help, I create this answer to simplify, and summarize all the ideas that was discussed.
The questions has 2 requisites:
Message level security;
One time authentication.
With ag112 help, this is hard to do, or to elegant in any way. So here are to conclusions:
For message level security send the user
credentials every time (place it in SOAP header);
For one time authentication use transport level security, and do a
session management.
I prefer the first one, because the message level was the biggest requisite.
As had no answers, following #unhillbilly advise, I answer my own question, with the progress so far:
How to know the name of the web method
being called;
Using a SOAP handler, finding the name of the first element in the body.
What kind of token should I use;
I decide to use a 128 bits token, representing each session. The Webservices, continue to be session-less, the key is just for authorizations purposes.
How to pass this token between calls.
For the login web method the result has the token, in each subsequent calls, the token is a parameter.
is there a better answer?