Re: Admin password for Tomcat
Jerry, On 12/30/23 01:20, Jerry Malcolm wrote: Chris, On 12/29/2023 11:22 AM, Christopher Schultz wrote: Jerry, On 12/28/23 18:33, Jerry Malcolm wrote: Chris, On 12/28/2023 3:38 PM, Christopher Schultz wrote: Jerry. On 12/27/23 02:13, Jerry Malcolm wrote: I implemented the filter as you suggested. But I guess I'm going to need some education on sessions. Down in a user profile web page I have a button to "Impersonate". I'm with you so far. I create the GenericPrincipal object and store it in the session. I've checked several times, and every time I come back to that code, the attribute is set in the session object. Good. When you do that, do you remove the "real" user's GenericPrincipal object from the session? Or are they both in there? > Sorry... lost you on that one. I am just setting a custom > "GenericPrincipal" attribute named "impersonatedPrincipal" in the session when a user clicks the "Impersonate" button on the web page. This answers my question. I was wondering if you do this: session.setAttribute("user", impersonatedUser); // Replace or this: session.setAttribut("impersonatedUser", impersonatedUser); And it seems you are doing the second one. In my understanding, at this point I'm just 'telling' the session that on subsequent requests in the custom filter, here's a principal object that I want to insert. As long as your code agrees with you :) I also noted in your early example that you stored a 'User' class as the attribute in the session, not a GenericPrincipal. I couldn't find a "User" class. So I just used GenericPrincipal, since that was what I will insert in the request object in the filter. We use User in our session, and essentially wrap it in a GenericPrincipal when necessary. We are playing a lot of games, here, in our code, so I apologize if we go down this road and it's a lot longer than you had expected... Remember that if Tomcat is going to enforce your authentication and authorization constraints, your Filter will run after that, and Tomcat and your application will disagree over which user is currently logged-in. > I'm not removing the real principal from anything. Not sure how to do that? in HttpSession? in HttpRequest? I assumed returning my new GenericPrincipal in the RequestFacade would override any other code asking for the principal. It will... unless that code runs before your Filter has a chance to pull the wool over the application's eyes. For example... Tomcat's authentication and authorization code will run in a Valve, which runs before all Filters. How do I go about removing the real principal? Let's save that for later ;) But when I put breakpoint in my new Filter object and look in the session, no attribute. It's a different session object from what I can tell. That's weird. When you say "every time I come back to that code, the attribute is set in the session" ... what code are you taking about? > The filter's 'version' of the session doesn't have the "impersonatedPrincipal" attribute set (it doesn't have any attributes set). But after clicking Impersonate, hitting the breakpoint, and watching the session attribute get set, I hit F5 to refresh the page. The filter breakpoint again doesn't have the attribute. But if I click "Impersonate" again and hit that breakpoint the "impersonatedPrincipal" session attribute exists in the session. Is the session identifier changing? I really thought I understood session objects. I thought there was only one session object throughout the processing of a servlet. Yes, if s/servlet/request/. But I'm obviously missing something in the flows. Why is there a different session object in the filter than in the main body of the servlet? I did the getSession(false) as you suggested. The session object is not null. It just doesn't have the attribute set. Yet if I hit the Impersonate button again and hit the breakpoint, the GenericPrincipal attribute is sitting in the session just as I placed it earlier. If the difference between when Tomcat evaluates e.g. user-roles versus when your application does won't explain what's happening, we might need to see some code. Code: Other than a loop that builds a Roles vector, these are the two lines that create the session attribute when the "Impersonate" button is clicked. GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); getCtrl().getRequest().getSession(false).setAttribute( "impersonatedPrincipal", newPrincipal ); Hmm. What are Ctrl and Request that you are "getting"? Usually, both the servlet and the Filter see objects passed to them directly in the doFilter() and service()/doGet/doPost/whatever methods in the servlet. And this is the filter: PrintWriter out = response.getWriter(); HttpSession session = ((HttpServletRequest)request).getSession(false); if(session != null) { final GenericPrincipa
Re: Admin password for Tomcat
Chris, On 12/29/2023 11:22 AM, Christopher Schultz wrote: Jerry, On 12/28/23 18:33, Jerry Malcolm wrote: Chris, On 12/28/2023 3:38 PM, Christopher Schultz wrote: Jerry. On 12/27/23 02:13, Jerry Malcolm wrote: I implemented the filter as you suggested. But I guess I'm going to need some education on sessions. Down in a user profile web page I have a button to "Impersonate". I'm with you so far. I create the GenericPrincipal object and store it in the session. I've checked several times, and every time I come back to that code, the attribute is set in the session object. Good. When you do that, do you remove the "real" user's GenericPrincipal object from the session? Or are they both in there? > Sorry... lost you on that one. I am just setting a custom > "GenericPrincipal" attribute named "impersonatedPrincipal" in the session when a user clicks the "Impersonate" button on the web page. This answers my question. I was wondering if you do this: session.setAttribute("user", impersonatedUser); // Replace or this: session.setAttribut("impersonatedUser", impersonatedUser); And it seems you are doing the second one. In my understanding, at this point I'm just 'telling' the session that on subsequent requests in the custom filter, here's a principal object that I want to insert. As long as your code agrees with you :) I also noted in your early example that you stored a 'User' class as the attribute in the session, not a GenericPrincipal. I couldn't find a "User" class. So I just used GenericPrincipal, since that was what I will insert in the request object in the filter. We use User in our session, and essentially wrap it in a GenericPrincipal when necessary. We are playing a lot of games, here, in our code, so I apologize if we go down this road and it's a lot longer than you had expected... Remember that if Tomcat is going to enforce your authentication and authorization constraints, your Filter will run after that, and Tomcat and your application will disagree over which user is currently logged-in. > I'm not removing the real principal from anything. Not sure how to do that? in HttpSession? in HttpRequest? I assumed returning my new GenericPrincipal in the RequestFacade would override any other code asking for the principal. It will... unless that code runs before your Filter has a chance to pull the wool over the application's eyes. For example... Tomcat's authentication and authorization code will run in a Valve, which runs before all Filters. How do I go about removing the real principal? Let's save that for later ;) But when I put breakpoint in my new Filter object and look in the session, no attribute. It's a different session object from what I can tell. That's weird. When you say "every time I come back to that code, the attribute is set in the session" ... what code are you taking about? > The filter's 'version' of the session doesn't have the "impersonatedPrincipal" attribute set (it doesn't have any attributes set). But after clicking Impersonate, hitting the breakpoint, and watching the session attribute get set, I hit F5 to refresh the page. The filter breakpoint again doesn't have the attribute. But if I click "Impersonate" again and hit that breakpoint the "impersonatedPrincipal" session attribute exists in the session. Is the session identifier changing? I really thought I understood session objects. I thought there was only one session object throughout the processing of a servlet. Yes, if s/servlet/request/. But I'm obviously missing something in the flows. Why is there a different session object in the filter than in the main body of the servlet? I did the getSession(false) as you suggested. The session object is not null. It just doesn't have the attribute set. Yet if I hit the Impersonate button again and hit the breakpoint, the GenericPrincipal attribute is sitting in the session just as I placed it earlier. If the difference between when Tomcat evaluates e.g. user-roles versus when your application does won't explain what's happening, we might need to see some code. Code: Other than a loop that builds a Roles vector, these are the two lines that create the session attribute when the "Impersonate" button is clicked. GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); getCtrl().getRequest().getSession(false).setAttribute( "impersonatedPrincipal", newPrincipal ); Hmm. What are Ctrl and Request that you are "getting"? Usually, both the servlet and the Filter see objects passed to them directly in the doFilter() and service()/doGet/doPost/whatever methods in the servlet. And this is the filter: PrintWriter out = response.getWriter(); HttpSession session = ((HttpServletRequest)request).getSession(false); if(session != null) { final GenericPrincipal impersonatedPrincipal = (GenericPrincipal) ses
Re: Admin password for Tomcat
Jerry, On 12/28/23 18:33, Jerry Malcolm wrote: Chris, On 12/28/2023 3:38 PM, Christopher Schultz wrote: Jerry. On 12/27/23 02:13, Jerry Malcolm wrote: I implemented the filter as you suggested. But I guess I'm going to need some education on sessions. Down in a user profile web page I have a button to "Impersonate". I'm with you so far. I create the GenericPrincipal object and store it in the session. I've checked several times, and every time I come back to that code, the attribute is set in the session object. Good. When you do that, do you remove the "real" user's GenericPrincipal object from the session? Or are they both in there? > Sorry... lost you on that one. I am just setting a custom > "GenericPrincipal" attribute named "impersonatedPrincipal" in the session when a user clicks the "Impersonate" button on the web page. This answers my question. I was wondering if you do this: session.setAttribute("user", impersonatedUser); // Replace or this: session.setAttribut("impersonatedUser", impersonatedUser); And it seems you are doing the second one. In my understanding, at this point I'm just 'telling' the session that on subsequent requests in the custom filter, here's a principal object that I want to insert. As long as your code agrees with you :) I also noted in your early example that you stored a 'User' class as the attribute in the session, not a GenericPrincipal. I couldn't find a "User" class. So I just used GenericPrincipal, since that was what I will insert in the request object in the filter. We use User in our session, and essentially wrap it in a GenericPrincipal when necessary. We are playing a lot of games, here, in our code, so I apologize if we go down this road and it's a lot longer than you had expected... Remember that if Tomcat is going to enforce your authentication and authorization constraints, your Filter will run after that, and Tomcat and your application will disagree over which user is currently logged-in. > I'm not removing the real principal from anything. Not sure how to do that? in HttpSession? in HttpRequest? I assumed returning my new GenericPrincipal in the RequestFacade would override any other code asking for the principal. It will... unless that code runs before your Filter has a chance to pull the wool over the application's eyes. For example... Tomcat's authentication and authorization code will run in a Valve, which runs before all Filters. How do I go about removing the real principal? Let's save that for later ;) But when I put breakpoint in my new Filter object and look in the session, no attribute. It's a different session object from what I can tell. That's weird. When you say "every time I come back to that code, the attribute is set in the session" ... what code are you taking about? > The filter's 'version' of the session doesn't have the "impersonatedPrincipal" attribute set (it doesn't have any attributes set). But after clicking Impersonate, hitting the breakpoint, and watching the session attribute get set, I hit F5 to refresh the page. The filter breakpoint again doesn't have the attribute. But if I click "Impersonate" again and hit that breakpoint the "impersonatedPrincipal" session attribute exists in the session. Is the session identifier changing? I really thought I understood session objects. I thought there was only one session object throughout the processing of a servlet. Yes, if s/servlet/request/. But I'm obviously missing something in the flows. Why is there a different session object in the filter than in the main body of the servlet? I did the getSession(false) as you suggested. The session object is not null. It just doesn't have the attribute set. Yet if I hit the Impersonate button again and hit the breakpoint, the GenericPrincipal attribute is sitting in the session just as I placed it earlier. If the difference between when Tomcat evaluates e.g. user-roles versus when your application does won't explain what's happening, we might need to see some code. Code: Other than a loop that builds a Roles vector, these are the two lines that create the session attribute when the "Impersonate" button is clicked. GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); getCtrl().getRequest().getSession(false).setAttribute( "impersonatedPrincipal", newPrincipal ); Hmm. What are Ctrl and Request that you are "getting"? Usually, both the servlet and the Filter see objects passed to them directly in the doFilter() and service()/doGet/doPost/whatever methods in the servlet. And this is the filter: PrintWriter out = response.getWriter(); HttpSession session = ((HttpServletRequest)request).getSession(false); if(session != null) { final GenericPrincipal impersonatedPrincipal = (GenericPrincipal) session.getAttribute("impersonatedPrincipal"); if (im
Re: Admin password for Tomcat
Chris, On 12/28/2023 3:38 PM, Christopher Schultz wrote: Jerry. On 12/27/23 02:13, Jerry Malcolm wrote: I implemented the filter as you suggested. But I guess I'm going to need some education on sessions. Down in a user profile web page I have a button to "Impersonate". I'm with you so far. I create the GenericPrincipal object and store it in the session. I've checked several times, and every time I come back to that code, the attribute is set in the session object. Good. When you do that, do you remove the "real" user's GenericPrincipal object from the session? Or are they both in there? Sorry... lost you on that one. I am just setting a custom "GenericPrincipal" attribute named "impersonatedPrincipal" in the session when a user clicks the "Impersonate" button on the web page. In my understanding, at this point I'm just 'telling' the session that on subsequent requests in the custom filter, here's a principal object that I want to insert. I also noted in your early example that you stored a 'User' class as the attribute in the session, not a GenericPrincipal. I couldn't find a "User" class. So I just used GenericPrincipal, since that was what I will insert in the request object in the filter. Remember that if Tomcat is going to enforce your authentication and authorization constraints, your Filter will run after that, and Tomcat and your application will disagree over which user is currently logged-in. I'm not removing the real principal from anything. Not sure how to do that? in HttpSession? in HttpRequest? I assumed returning my new GenericPrincipal in the RequestFacade would override any other code asking for the principal. How do I go about removing the real principal? But when I put breakpoint in my new Filter object and look in the session, no attribute. It's a different session object from what I can tell. That's weird. When you say "every time I come back to that code, the attribute is set in the session" ... what code are you taking about? The filter's 'version' of the session doesn't have the "impersonatedPrincipal" attribute set (it doesn't have any attributes set). But after clicking Impersonate, hitting the breakpoint, and watching the session attribute get set, I hit F5 to refresh the page. The filter breakpoint again doesn't have the attribute. But if I click "Impersonate" again and hit that breakpoint the "impersonatedPrincipal" session attribute exists in the session. I really thought I understood session objects. I thought there was only one session object throughout the processing of a servlet. Yes, if s/servlet/request/. But I'm obviously missing something in the flows. Why is there a different session object in the filter than in the main body of the servlet? I did the getSession(false) as you suggested. The session object is not null. It just doesn't have the attribute set. Yet if I hit the Impersonate button again and hit the breakpoint, the GenericPrincipal attribute is sitting in the session just as I placed it earlier. If the difference between when Tomcat evaluates e.g. user-roles versus when your application does won't explain what's happening, we might need to see some code. Code: Other than a loop that builds a Roles vector, these are the two lines that create the session attribute when the "Impersonate" button is clicked. GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); getCtrl().getRequest().getSession(false).setAttribute( "impersonatedPrincipal", newPrincipal ); And this is the filter: PrintWriter out = response.getWriter(); HttpSession session = ((HttpServletRequest)request).getSession(false); if(session != null) { final GenericPrincipal impersonatedPrincipal = (GenericPrincipal) session.getAttribute("impersonatedPrincipal"); if (impersonatedPrincipal != null) { System.out.println( "Impersonating"); request = new HttpServletRequestWrapper((HttpServletRequest)request) { public Principal getUserPrincipal() { return impersonatedPrincipal; } }; } } chain.doFilter(request, response); I feel like I'm right on top of the solution. But I just can't seem to get over the finish line. Thanks for you help. -chris - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
Jerry. On 12/27/23 02:13, Jerry Malcolm wrote: I implemented the filter as you suggested. But I guess I'm going to need some education on sessions. Down in a user profile web page I have a button to "Impersonate". I'm with you so far. I create the GenericPrincipal object and store it in the session. I've checked several times, and every time I come back to that code, the attribute is set in the session object. Good. When you do that, do you remove the "real" user's GenericPrincipal object from the session? Or are they both in there? Remember that if Tomcat is going to enforce your authentication and authorization constraints, your Filter will run after that, and Tomcat and your application will disagree over which user is currently logged-in. But when I put breakpoint in my new Filter object and look in the session, no attribute. It's a different session object from what I can tell. That's weird. When you say "every time I come back to that code, the attribute is set in the session" ... what code are you taking about? I really thought I understood session objects. I thought there was only one session object throughout the processing of a servlet. Yes, if s/servlet/request/. But I'm obviously missing something in the flows. Why is there a different session object in the filter than in the main body of the servlet? I did the getSession(false) as you suggested. The session object is not null. It just doesn't have the attribute set. Yet if I hit the Impersonate button again and hit the breakpoint, the GenericPrincipal attribute is sitting in the session just as I placed it earlier. If the difference between when Tomcat evaluates e.g. user-roles versus when your application does won't explain what's happening, we might need to see some code. -chris - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
Chris, On 12/26/2023 11:35 AM, Christopher Schultz wrote: Jerry, On 12/24/23 19:18, Jerry Malcolm wrote: Chris, On 11/8/2023 2:43 PM, Christopher Schultz wrote: Jerry, On 11/6/23 23:22, Jerry Malcolm wrote: On 11/5/2023 11:54 AM, Jerry Malcolm wrote: On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? Chris, I'm not having any luck googling info on how to replace the user principal object in the session object. This is exactly what I need to do. But looks like I'm going to need a little bit of guidance to figure out how to implement it. I forgot that "we" are using our own custom principal and actually not using Tomcat's authentication and authorization. So we do things differently. If you are using FORM authentication, then I think this is a little easier. You may have to do a nasty bit of casting to internal Tomcat classes and/or use reflection, but you can simply call: org.apache.catalina.Session.setPrincipal(java.security.Principal) The StandardSession class you probably are already getting from Tomcat implements that interface, so you should be able to call that. I think while Tomcat will accept any java.security.Principal, in practice, you'll want to use org.apache.catalina.realm.GenericPrincipal. -chris I finally had a minute to try to implement your suggestion from a few weeks ago. I got everything coded. But I'm getting a ClassCastException when trying to retrieve StandardSession. I'm getting a StandardSessionFacade object instead of StandardSession. I looked at the javaDoc hoping to find a way to get the StandardSession from the facade object. But no luck. Am I not going about this correctly in my code? How can get access to the StandardSession object instead of the StandardSessionFacade object? Thx GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); ((StandardSession)getCtrl().getRequest().getSession()).setPrincipal( newPrincipal ); Hmm. It seems that StandardSessionFacade is used to prevent the kind of thing you are trying to do, probably as a protection against potentially malicious applications. If you are willing to get messier, you can use reflection to get the value of the StandardSessionFacade.session member, which will be a StandardSession object. Another option is to do what my application does, which is to store the user in a session attribute and then wrap each request in a Filter making it available: doFilter(...) { HttpSession s = request.getSession(false); if(null != s) { final User u = s.getAttribute("user"); if(null != u) { // Wrap request request = new HttpServletRequestWrapper(request) { public Principal getUserPrincipal() { return u; } }; } } chain.doFilter(request, response); } The above is psuedocode ty
Re: Admin password for Tomcat
Jerry, On 12/24/23 19:18, Jerry Malcolm wrote: Chris, On 11/8/2023 2:43 PM, Christopher Schultz wrote: Jerry, On 11/6/23 23:22, Jerry Malcolm wrote: On 11/5/2023 11:54 AM, Jerry Malcolm wrote: On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? Chris, I'm not having any luck googling info on how to replace the user principal object in the session object. This is exactly what I need to do. But looks like I'm going to need a little bit of guidance to figure out how to implement it. I forgot that "we" are using our own custom principal and actually not using Tomcat's authentication and authorization. So we do things differently. If you are using FORM authentication, then I think this is a little easier. You may have to do a nasty bit of casting to internal Tomcat classes and/or use reflection, but you can simply call: org.apache.catalina.Session.setPrincipal(java.security.Principal) The StandardSession class you probably are already getting from Tomcat implements that interface, so you should be able to call that. I think while Tomcat will accept any java.security.Principal, in practice, you'll want to use org.apache.catalina.realm.GenericPrincipal. -chris I finally had a minute to try to implement your suggestion from a few weeks ago. I got everything coded. But I'm getting a ClassCastException when trying to retrieve StandardSession. I'm getting a StandardSessionFacade object instead of StandardSession. I looked at the javaDoc hoping to find a way to get the StandardSession from the facade object. But no luck. Am I not going about this correctly in my code? How can get access to the StandardSession object instead of the StandardSessionFacade object? Thx GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); ((StandardSession)getCtrl().getRequest().getSession()).setPrincipal( newPrincipal ); Hmm. It seems that StandardSessionFacade is used to prevent the kind of thing you are trying to do, probably as a protection against potentially malicious applications. If you are willing to get messier, you can use reflection to get the value of the StandardSessionFacade.session member, which will be a StandardSession object. Another option is to do what my application does, which is to store the user in a session attribute and then wrap each request in a Filter making it available: doFilter(...) { HttpSession s = request.getSession(false); if(null != s) { final User u = s.getAttribute("user"); if(null != u) { // Wrap request request = new HttpServletRequestWrapper(request) { public Principal getUserPrincipal() { return u; } }; } } chain.doFilter(request, response); } The above is psuedocode typed from memory. I'm fairly sure we create a new Principal
Re: Admin password for Tomcat
Chris, On 11/8/2023 2:43 PM, Christopher Schultz wrote: Jerry, On 11/6/23 23:22, Jerry Malcolm wrote: On 11/5/2023 11:54 AM, Jerry Malcolm wrote: On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? Chris, I'm not having any luck googling info on how to replace the user principal object in the session object. This is exactly what I need to do. But looks like I'm going to need a little bit of guidance to figure out how to implement it. I forgot that "we" are using our own custom principal and actually not using Tomcat's authentication and authorization. So we do things differently. If you are using FORM authentication, then I think this is a little easier. You may have to do a nasty bit of casting to internal Tomcat classes and/or use reflection, but you can simply call: org.apache.catalina.Session.setPrincipal(java.security.Principal) The StandardSession class you probably are already getting from Tomcat implements that interface, so you should be able to call that. I think while Tomcat will accept any java.security.Principal, in practice, you'll want to use org.apache.catalina.realm.GenericPrincipal. -chris I finally had a minute to try to implement your suggestion from a few weeks ago. I got everything coded. But I'm getting a ClassCastException when trying to retrieve StandardSession. I'm getting a StandardSessionFacade object instead of StandardSession. I looked at the javaDoc hoping to find a way to get the StandardSession from the facade object. But no luck. Am I not going about this correctly in my code? How can get access to the StandardSession object instead of the StandardSessionFacade object? Thx GenericPrincipal newPrincipal = new GenericPrincipal( getUserName(), getPassword(), roles ); ((StandardSession)getCtrl().getRequest().getSession()).setPrincipal( newPrincipal ); - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
Jerry, On 11/6/23 23:22, Jerry Malcolm wrote: On 11/5/2023 11:54 AM, Jerry Malcolm wrote: On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? Chris, I'm not having any luck googling info on how to replace the user principal object in the session object. This is exactly what I need to do. But looks like I'm going to need a little bit of guidance to figure out how to implement it. I forgot that "we" are using our own custom principal and actually not using Tomcat's authentication and authorization. So we do things differently. If you are using FORM authentication, then I think this is a little easier. You may have to do a nasty bit of casting to internal Tomcat classes and/or use reflection, but you can simply call: org.apache.catalina.Session.setPrincipal(java.security.Principal) The StandardSession class you probably are already getting from Tomcat implements that interface, so you should be able to call that. I think while Tomcat will accept any java.security.Principal, in practice, you'll want to use org.apache.catalina.realm.GenericPrincipal. -chris - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
On 11/5/2023 11:54 AM, Jerry Malcolm wrote: On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? Chris, I'm not having any luck googling info on how to replace the user principal object in the session object. This is exactly what I need to do. But looks like I'm going to need a little bit of guidance to figure out how to implement it. Thanks. Jerry - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
On 11/5/2023 9:26 AM, Christopher Schultz wrote: Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris Hi Chris, it's my own webapp. Changing user principal is exactly what I'm trying to do. I wasn't aware that the user principal could be easily swapped. Where can I learn more about how to do that? - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
Jerry, On 11/4/23 20:17, Jerry Malcolm wrote: My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? This sounds like "impersonation" to me, which, I think, can be done differently. If you are indeed describing an X-Y problem above, then might I suggest the following? Instead of figuring out how to "add" a second password to a user, what about allowing you to login as e.g. "jerry" and then assume the identity of the user "tom"? You should be able to do this by changing the UserPrincipal in the session to have a different username. Which application are you trying to do this with? Your own application, or one which ships with Tomcat (e.g. Manager)? -chris - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
Jerry, > Am 05.11.2023 um 02:34 schrieb Brian Wolfe : > > You need to build a custom realm for that if you're using tomcat to manage > your user sessions and not creating your own sessions for your application. > You can extend the existing one that you're using. I assume you're using > the JDBC Realm since you said you have an USERS table. So you could add > another field to your table and extend the JDBC class to do an additional > check on your admin pwd field if you don't want them to have a second > account. > > https://tomcat.apache.org/tomcat-9.0-doc/realm-howto.html#Standard_Realm_Implementations > > You will want to look at the source of the realm implementation to see how > you need to extend it. So you shouldn't have to do too much to get the > functionality you're looking for. > >> On Sat, Nov 4, 2023 at 8:18 PM Jerry Malcolm wrote: >> >> My support team needs to be able to log in to our site as various users >> (on behalf of...) to be able to see exactly what they are seeing since >> roles, access groups, history is different for different users. I would >> like to implement an admin password where I can log in as any userId >> with this password. I totally realize the security risks involved in >> this. But I am handling the security risks with additional >> authorizations. Back in the days when we had this requirement, we implemented an "admin tool" where we had the admin user login as themselves and then pick the user they wanted to see. At this time the password check was simply skipped. No fiddling with the password table, no security flaws as the admin tool was not available to the public. >> I simply need to make every user have two passwords... >> their real personal password, and the admin password. The only >> alternative I have right now is to save off the user's password hash in >> the USERS table, replace it with my password hash, then restore the >> user's original password when I'm done. I'm not thrilled with that >> solution first because it's a pain and error prone, and also because the >> user can no longer log in while their password is replaced with my >> password. >> >> I figure this function is buried in the authenticator code somewhere. >> But I'd first like to see if anybody has done anything like this >> already. If not, could somebody point me in the right direction to the >> tomcat source file that I'm going to need to modify and also what's >> involved in making authentication use my updated class instead of the >> default. >> >> Suggestions? >> Would that be a solution? Peter >> Thx >> >> Jerry >> >> >> - >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org >> For additional commands, e-mail: users-h...@tomcat.apache.org >> >> > > -- > Thanks, > Brian Wolfe > https://www.linkedin.com/in/brian-wolfe-3136425a/ - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Admin password for Tomcat
You need to build a custom realm for that if you're using tomcat to manage your user sessions and not creating your own sessions for your application. You can extend the existing one that you're using. I assume you're using the JDBC Realm since you said you have an USERS table. So you could add another field to your table and extend the JDBC class to do an additional check on your admin pwd field if you don't want them to have a second account. https://tomcat.apache.org/tomcat-9.0-doc/realm-howto.html#Standard_Realm_Implementations You will want to look at the source of the realm implementation to see how you need to extend it. So you shouldn't have to do too much to get the functionality you're looking for. On Sat, Nov 4, 2023 at 8:18 PM Jerry Malcolm wrote: > My support team needs to be able to log in to our site as various users > (on behalf of...) to be able to see exactly what they are seeing since > roles, access groups, history is different for different users. I would > like to implement an admin password where I can log in as any userId > with this password. I totally realize the security risks involved in > this. But I am handling the security risks with additional > authorizations. I simply need to make every user have two passwords... > their real personal password, and the admin password. The only > alternative I have right now is to save off the user's password hash in > the USERS table, replace it with my password hash, then restore the > user's original password when I'm done. I'm not thrilled with that > solution first because it's a pain and error prone, and also because the > user can no longer log in while their password is replaced with my > password. > > I figure this function is buried in the authenticator code somewhere. > But I'd first like to see if anybody has done anything like this > already. If not, could somebody point me in the right direction to the > tomcat source file that I'm going to need to modify and also what's > involved in making authentication use my updated class instead of the > default. > > Suggestions? > > Thx > > Jerry > > > - > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > > -- Thanks, Brian Wolfe https://www.linkedin.com/in/brian-wolfe-3136425a/
Admin password for Tomcat
My support team needs to be able to log in to our site as various users (on behalf of...) to be able to see exactly what they are seeing since roles, access groups, history is different for different users. I would like to implement an admin password where I can log in as any userId with this password. I totally realize the security risks involved in this. But I am handling the security risks with additional authorizations. I simply need to make every user have two passwords... their real personal password, and the admin password. The only alternative I have right now is to save off the user's password hash in the USERS table, replace it with my password hash, then restore the user's original password when I'm done. I'm not thrilled with that solution first because it's a pain and error prone, and also because the user can no longer log in while their password is replaced with my password. I figure this function is buried in the authenticator code somewhere. But I'd first like to see if anybody has done anything like this already. If not, could somebody point me in the right direction to the tomcat source file that I'm going to need to modify and also what's involved in making authentication use my updated class instead of the default. Suggestions? Thx Jerry - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org