36 Web Security
Pravin Jain
Introduction
Welcome to this module on web security. In the previous module, we had looked at security in jdk, security in general rather, where we talked about the key pairs, we talked about hashing, we talked about what is digital certificate, what is meant by digital signing etc so that was more useful in integrity aspect. Those key elements are also useful in web applications. Now we have another things which is about security for web applications.
Declarative security
In web applications, especially java based web applications we have got various mechanisms of securing our components. in the web application. By securing what we mean here is, we would like to have certain URLs or certain resources which have to be protected from used by unauthorized person. When we say unauthorized person, we mean that there has to be some mechanism to identify persons.
Authentication and role-based authorization
This is what we call as authentication. so authentication is nothing but a process by which the client can be identified. We have an identity of the client and there are a few other things. so a client or a group of clients is authorized means they have a particular role. We have a concept of role also. Each and every person should have a role. Person is identified to have a certain kind of role. A person has a authentication so a person has to be authenticated. When a person is authenticated his role is also being identified. So, who does this? Who will manage the role of the person? is it the application? Not necessarily. Application has its own set of components. The developer is not supposed to worry about who is authorized and who is not authorized. There are very little places where he may think, that this particular component has to be available only to someone having the role of an administrator . There might be only few such components which are role based. And most of the places, maybe a particular application is being deployed. Rather than someone from the application side trying to determine who is who, how to find out and authenticate, the mechanism of authentication. That authentication mechanism, if we recollect is also something which can be taken as responsibility by our containers, the java containers.
So, given a web container, every web container would have its own mechanism of authentication. Rather than managing the roles and person, determining who is who, having a valid list of who are the users and some mechanism of what should be the mechanism for authentication. For example, the authentication related information. very commonly we have got the things like username and password, that is one kind of mechanism for authenticating and finding out if this is that person is authorized or not. So, such things, managing these peoples, managing the users is something which can be done by container. So different web server will have their own mechanisms to manage this, For Example, in case of tomcat, there are various options available , one of those options is where you could say, where we can specify all the users which are there in a kind of a file, its an XML file called tomcat-users.xml. So you could update the tomcat- users.xml to contain list of valid roles, so you have entries for the roles, and then creating entries for the users where you will say this user has this name, and that’s his password and this user has these kind of roles. A list of roles can be assigned to a user. This user :- he is having all these roles. That way , a file can be used. Tomcat is using such a mechanism. Each and every container has its own mechanism of managing this.
Now authentication would then become the responsibility of container. But how to have authentication being carried out? It would be done by container but how should it be done? What kind of interface should be given? So we have got various kinds of options. And this is the information which would be given in our deployment descriptor. And for our web application we got our descriptor , that web.xml file, within that file you could make an entry which says: whenever authentication is required, whenever we need to know who is the current client, I would like you to use a particular kind of authentication mechanism.
So in web.xml we got entries to find out who that person is. So we got entries in the web.xml( the deployment descriptor), for example we have an entry called <login- config>. we have a tag of <login-config> which has authorization mechanism, it has authmode where you can say how authentication should be done. It could to be a form based authentication, very commonly it could be a form based authentication, in case of a form based authentication the application developer would be able to design his own page for login and he also has to design another page. In case the login fails, he need to have another page so these would be created mostly as JSP files.
auth-mode
There are some requirements for these JSP files, the kind of entries which go in the web.xml: we have a <login-config>, we have <auth-mode> where we will might specify FORM, there are other authmodes for example you can say use BASIC, if you specify BASIC, you don’t have to do anything just give the name.If you say BASIC its actually the browser that has to pop-up, it will pop-up a small window which would ask for login id and password, you don’t have to design any form or anything. But if you have said the auth-mode is FORM you need to also specify <login-form-config>, you have a inner tag called <login-form-config>, In that case you mention two entries: there would be <login- form-page> and <login-error-page> . So we have got <login-form-page> and <login- error-page> to link to a JSP. for example you can start with a slash(/) here and you can put the location within your web application where you got the JSP. For example, you can say <login-form-page>/loginpage.jsp</login-form-page>, that is one entry and you have other entry <login-error-page>/loginerror.jsp</login-error-page>, if there is a login error, the page which has to show the error message and whatever else you can determine what it is. You can create your own login-error-page and that should be mentioned with the <login-error-page> . So that’s a kind of entry which goes if you want a form based authentication. So that’s about what is the mechanism used for authentication. Once you have decided the method used for authentication. Of course if it is form based, you have to create those two components also, those two JSPs basically. So that’s one aspect . We have one aspect for what is the method of login authentication
So now another thing is you would like to protect some URLs. This url is the one which requires a particular role, So we can do this just by declaration in our web.xml file. Its all declarative we don’t have to write anything in java code at all. So we can say I want to have some kind of security constraint . You can put your security constraints on the urls. What we have here is a tag called <security-constraint>. Within this tag you could add a inner tag which has a group of urls. To have a group of urls we have a <web-resource- collection> tag, having a inner tag called <web-resource-name> and <url-pattern>. So a web resource name and url pattern creates a set of urls, its a collection of urls. One of the things in our web.xml in the <security-constraints> tag is the <web-resource- collection>. We can have several such web resource collections but then this is only one security constraint, so in this security constraint I want a particular role only for this set of resources . It is one set of resources and another set of resources ,a set of resources having a name and a url pattern. And then i would like them to have a particular kind of role. One more thing, the roles which you want to have, all that has to be listed, in the web.xml file. All the valid roles have to be listed. So they have to be listed independently they are not within the security constaint. In web.xml you have something called <security-role> and within <security-role> there is an inner tag called <role-name> where you just give the role name. Create such security roles for every role available to you, which is going to be used in the web.xml file. Now we are asking that a particular role has to be used for this set of resources, so we have a tag specifying which role is necessary. so we have this entry which goes in web.xml which specifies that this particular role is required. So we have authconstraint. Within authconstraint we will have role name and give the list of roles. So you can put multiple role entries and say these are the roles which are allowed for this particular set of resources.
Now if you have your form based authentication, for a form based authentication you will be creating some jsp page, but there are a few requirements for the jsp pages. The authentication is done by the container. the application is not doing it. The application developer is simply creating an interface, so in this interface which the application developer creates there are specific requirements of this. you may design whatever way you like, but then it should have a form entry, it would be html kind of entry which has a form tag, in the form tag you would have action=’…’, a specific value, would be there which would be used by container, so we have j_security_check. so action= should always be j_security_check ie. action=’j_security_check’. Again when we put the input tags , input type=”text” ,you will have a username , so for accepting this username we have name= “j_username” in the input tag. And then we also will have a password field and for the password field normally we will say input type= “password” , in this case the name should always be j_password. So these three values are specific to any container, whatever web container you may be having you always design your jsp with these three things: the method of the form most of the time you would have as post but the action should have j_security_check, input for username should be j_username and input for password should be j_password. So this is one more requirement for the jsp which you develop for your login page, in your <login-page-config>.
Now continuing further the next requirement would be, you would have your data but within this whatever data is there that has to be authenticated. Many times you have certain set of urls for which you would have that this particular data, whatever the data part is coming that content even in transit, if someone is able to get hold of it, should not be able to make out, I want that to be confidential.. You have some https, you will have to enable https things, https will actually require that key pair what we had talked earlier , the key pair for which the public key for your server would be available to the client and the private key is used here. we have a mechanism for exchange of the data, it would use SSL. So there would be a SSL which would be used for communication , I have certain set of URL for which the content has to be transported in such a way that it has to be a confidential one. so for that you don’t have to do much things in your web application, what you need to do is in the web.xml file, you have the <security- constraint>, the same things, those security constraints have a set of resources by saying <web-resource-collections> having the inner tags to manage the resource collection using the <url-pattern> and name, so you have such a thing, and you may have <auth-constraint> also since this is confidential it may also require that it is available for specific roles only, it may or may not require a role. If it doesnt require a role then you would not have an <auth-constraint> but you would have a <user-data- constraint>. The user data, the content here that has a constraint that this needs to have a transportation which would be confidential. So transport mechanism has to be confidential. So you have a tag there for specifying that transport has to be confidential.
So you can see this is all declarative and by using just the declarations, you are able to manage security. This is one aspect that we have a declarative way of specifying our security.
Programmatic security
What are the things we have done, we have specified a set of roles, but before that container has the responsibility of doing all the authentication.Now container has done the authentication, but its the servlet here which would like to know who is the current user. So for that now we have something in our program, within our servlet, within any of our java components. There is some component which would like to know if the request comes from a client who has been authenticated, whether the proper person is there or not, the person who has been authenticated, what kind of role he is having. Does he have a role of particular kind or not. So if you want to determine such thing we have in the HttpServeletRequest, this method called isUserInRole, where you can specify a role name and get a Boolean value, true or false, so whether the current user(logged in user) has particular role.
public boolean isUserInRole(String rolename)
One would normally like to use these role based things. But at some times you might like to know the name of the user. Who is that remote user? if you are interested in knowing who that remote user is in the HttpServeletRequest we even have a method called getRemoteUser(), to give us the name of the user, if no authentication is carried out it would return a null value, so if it is returning a null value you could redirect and send it back and say error 401.
public String getRemoteUser()
So we have those kind of response code so it would force a authentication from the client if he is not been authenticated. So that’s something you can do from within any of your java component on the server side. Another thing I would also like to know is how the authentication is carried out. If it is basic authentication maybe it is not so secured, we have form based authentication almost similar , but we even can have client certificate being used as authentication. In that authmode tag you could have said client certificate so has it been authenticated by using client certificate, or which kind of authentication was used. So, for that HttpServerRequest also has a method called getAuthType(), which returns a String so that string would be saying its basic or its form or its authcert . which particular kind of authentication is carried out ,that can always be determined by any java component on our server.
public String getAuthType()
So server has to do the authentication and all its information is made available by ServletRequest to our java components or it can be even a JSP which is trying to use that information. We have that getRemoteUser() method and we also have an old method called getPrincipal() which returns an object of Principal,
public Principal getPrincipal()
this Principal is there from the beginning of servlet API , that was an old way it has nothing much then having a name. this getPrincipal() returns a Principal which is available in java.security package and the principal has nothing but a method called getName(), so it is almost equivalent of using the getRemoteUser() method. These are some of the method which are available for our programmatic thing.
So you pro-grammatically want to check anything you have java components having these methods. So this is one aspect of our web security. One thing we require for our web security is that we need our transportation to be confidential and to keep the transport confidential we require to set up our SSL. In order to set up our SSL we have to update our server, (this would again depend from server to sever), so for tomcat there is a server.xml and you will have to make entries there. You will have to ensure that ssl is enabled for the server side, But one important thing, what you need here is a certificate, you will need a key pair to be generated for our server and in this key pair the public key of the key pair should be available with the clients. The server would keep the private key, it would have a key store so you will have to use the keytool which is able to mange a key store for us . So you can manage a key store , so for your web application you need a key pair. And that has to be known to the server how to use it and server should be able to use particular alias from that key store. The client should be able to authenticate. The key pair which you generate, it has to be something which is endorsed, so your key store should normally have certificates which are signed by authorized agencies. Certificates are nothing but public keys. So you got your certificates available globally, and in most of the softwares it is available only for the certifying authorities. When we have a certificate being signed, these certifying authorities have their own self signed certificates, that’s one thing, but then there is a chain of certificates, if something is being signed a certifying authority has its own sub-certifying authorities. You may be having a certificate that is not signed by the certifying authority directly but by a sub-certifying authority. So if there is a sub-certifying authority, the certificate that you have, has a chain of certificates. So we don’t just have a certificate entry in a key store, we would have a chain of certificates. For example, certificate issued to us by a subcertifying authority, which would have a certificate of the subcertifying authority which would be signed by the actual certifying authority and for that certifying authority it would have a self signed certificate. So at the root there is a self signed certificate. The self signed certificate is the top certificate and that should be publicly available to us and it should be a trusted certificate in our key store, if we have a key store in which this certificate is there as a trusted certificate only than it can work. So you will have a lot of tasks here to set up a certificate. Many times maybe you don’t want to have the cost of having a certificate from a certifying authority because in order to maintain a certificate there is some annual recurring cost associated with the certificate issued by the certifying authority . Instead of using those you may be interested in generating your own key pair . So if you are generating your own key pair using key tool, in that you have your own self signed certificate, but then you will have a task of distributing this self signed certificate even to all your client, they will have to manage it in their browser, browsers also manage their key stores, so this certificate would also be managed in the browser. For that we have commands in the key tool for exporting our certificate. If there is a key entry you can export the certificate out of your key store by using a key tool command. So key tool -export is available. And on the other side if there is a key store being used by an application the application can use the key tool -import to import certificate in order to add a certificate entry into his key store. Key store management can be done by key tool. You will need a lot of those things if you are interested in setting up a ssl, you will need to do a lot of exercise on that also.
So security in web side is quite involved if you are interested in ssl. But if you are interested in just securing some urls then things are quite simple and can be done by just using our declarations in the web.xml file. You have a security constraint, you have a login constraint and you need to remember you will be using a security role and mention all the logins which are available. Now another point is you may have created certain servlets and these servelts have been created by someone else and you are just trying to use them , those servlets also use a particular role.
Now when we have servlet using a specific role for that role, the role which is used be there, may not be exactly the role which we have here in our current server. on server, on our web container it uses a particular set of roles for which it has been configured , But we have our serverside, we have our java component which would like to use certain role but they have a different name, they have a equivalent role here , there maybe a one to one role so there is a one to one mapping , someone says this is admin. On the other side the servlet or the java component which you are trying to use, the role called is manager but within the container the role is understood as admin, Now what do I do? Do I recompile? But I don’t have the code for the servlet, I am interested in using that servlet component but I don’t have the code with me or do i recompile and ask everyone to deploy it again? I have coded in one but this application is deployed in different places. At different places equivalent of the manager which is used in my servlet. In my servlet I am using isUserInRole(“manager”), but some places it is admin, someone says administrator, someone may have a different name altogether but they are equivalent of what is manager for my server, so how do I use that servlet? it would be a big maintenance task for managing a different servlet which has been compiled with different values for that particular role for each different places where i have deployed it. So rather than that, there has to be some mechanism within my container, within my web.xml. So within the web.xml when we make a servlet entry we can put an entry to let the container know that if the servlet API looks for this particular role you should understand that actually this is the particular role. So you will say there is a servlet role that is manager because that’s what my servlet understand but it will link role, so it has a <role-link> it is linked to use admin on this particular deployment. So you have your application deployed at different places when it is been deployed in the servlet the servlet is only using a specific role name and at different places in the web.xml the admin there has to configure and say we have that manager which used by our servlet in this application but on our deployment here our container doesnt understand manager the equivalent of manager on our container is, and I can give that so these are some entries which we can make in our web.xml.
And in this web.xml for the servlet entry we have <security-role-ref>, there is an entry which is inside the <servlet> entry we have <security-role-ref> and within that we have <role-name> which is understood by the server and we will say <role-link>, this is link to the role that the container understand . So you can deploy web application even in different kinds of mechanisms and role names . And this is all very declarative and simplified. It is only if we have requirement of ssl that is where more task will have to be done otherwise most of the things are managed just by declaration.
Thats what we have in this module.
you can view video on Web Security |
Suggested Reading:
- Core Servlets and Java Server Pages Volume 2 by Marty Hall & Larry Brown, Second Edition, Pearson Education.
- Core Java Volume 2 by Cay Horstmann & Gary Cornell, Ninth Edition, Pearson Education.
- Java Security by Scott Oaks, 2nd Edition O’Reilly Media
- http://docs.oracle.com/javaee/6/tutorial/doc/bncat.html