锘??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲av永久无码精品网址,国产亚洲av片在线观看播放,日韩亚洲欧洲在线com91tvhttp://www.tkk7.com/lmsun/category/2788.htmlzh-cnWed, 28 Feb 2007 20:24:43 GMTWed, 28 Feb 2007 20:24:43 GMT60JAAS Security in Actionhttp://www.tkk7.com/lmsun/articles/11031.htmlmy javamy javaThu, 25 Aug 2005 05:43:00 GMThttp://www.tkk7.com/lmsun/articles/11031.htmlhttp://www.tkk7.com/lmsun/comments/11031.htmlhttp://www.tkk7.com/lmsun/articles/11031.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11031.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11031.htmlThis 10-Minute Solution provides a brief introduction to the JAAS (pronounced "Jazz") architecture, API, and programming model. It covers both authentication and authorization with JAAS, providing full working code examples that demonstrate JAAS security in action.



How do I implement security, one of the most important aspects of today's software applications, into my Java environment when most security implementations are inflexible, proprietary systems?



The Java Authentication and Authorization Service (JAAS) is a flexible, standardized API that supports runtime pluggability of security modules.

What Is JAAS?
According to Sun's Web site, "The Java Authentication and Authorization Service (JAAS) is a set of packages that enables services to authenticate and enforce access controls upon users. It implements a Java version of the standard Pluggable Authentication Module (PAM) framework, and supports user-based authorization."

In practice, JAAS represents the new Java security standard, as it has formally been added to the JDK 1.4 code base. From an architectural standpoint, JAAS implements a Java version of the Pluggable Authentication Module (PAM) framework. First released in May 2000 by The PAM Forum, the framework is a modularized architecture designed to support the seamless exchange of one security protocol component for another. The framework allows multiple authentication technologies and/or authentication approaches to be added without changing or interfering with any of the existing login services. PAM can be used to integrate login services with various authentication technologies, such as RSA, DCE, Kerberos, S/Key, and even to support smart card-based authentication systems.

Authenticating with JAAS
JAAS authentication is deployed in a pluggable manner, using code modules that implement certain interfaces. This enables Java applications to remain decoupled from the underlying authentication technologies. Additional authentication protocols and updated authentication technologies can be plugged in at runtime without modifying the application or recompiling the source code.

The JAAS Authentication API is quite extensive. The key interfaces and classes that you need to familiarize yourself with are as follows:

  • Callback 鈥?Implementations of this interface encapsulate information (usernames, passwords, error and warning messages) that is exchanged between security services and a CallbackHandler.
  • CallbackHandler 鈥?An application implements a CallbackHandler and passes it to underlying security services to facilitate interaction between the security services and the application.
  • LoginContext 鈥?The LoginContext class provides the basic methods used to authenticate Subjects in a neutral manner, decoupled from the underlying authentication technology.
  • LoginModule 鈥?Authentication technology providers implement this interface to provide a particular type of authentication via a pluggable module.
  • Principal 鈥?The Principal interface represents the abstract notion of a principal, which can be used to represent any unique entity (individual, corporation, organization, login id, social security number, etc.) that can be authenticated.
  • Subject 鈥?A Subject object represents a grouping of related information for a single entity, such as a person. One or more Principals are bound to a subject. Each Principal represents one identity for the subject (name, social security #, etc.). A Subject also maintains security-related attributes (passwords and cryptographic keys, for example).
  • Authorization with JAAS
    JAAS authorization is built on top of JAAS authentication. It augments the existing code-centric access controls that were introduced with the Java 2 platform (JDK 1.2.x) with new user-centric access controls. In this way, JAAS authorization allows you to grant permissions based not on just what code is running but also on who is running it.

    After a user has been authenticated by JAAS, the authorization API associates the Subject (created to represent the authenticated entity) with an appropriate access control context. Whenever the Subject attempts a restricted operation (database access, local file access, etc.), the Java runtime consults the policy file to determine which Principal(s) may perform the operation. If the Subject in question contains the designated Principal, the Java runtime allows the operation. Otherwise, it throws an exception.

    You don't need to import additional packages to access the JAAS authorization features, because JAAS authorization is built on top of JAAS authentication. In addition to the classes and interfaces used in the authentication piece, one additional interface is of interest for the simple example in this Solution:

  • PrivilegedAction 鈥?This interface defines only one member, a method named run(). It accepts no parameters and returns type Object. A class wanting to restrict access to one or more actions implements this interface and puts the calls to the restricted functions within its run() method.
  • See JAAS in Action
    Included with this Solution is a downloadable zip file that contains all the source code and class files necessary to see JAAS authentication and authorization in action.

    advertisement

    Authentication Files

  • SimpleAuth.java 鈥?This file contains the main() method. It creates a LoginContext object by passing in a LoginModule configuration id ("JAAS_Module") and an instance of the CallbackHandler interface. The LoginContext reads a configuration file, looking for the configuration ID. Upon finding a match, it instantiates the specified LoginModules. Each LoginModule is initialized with a Subject, a CallbackHandler, shared LoginModule state, and LoginModule-specific options. Finally, the login process is kicked off by calling the login() method on the LoginContext object (which is implemented by the LoginModule class).
  • SimpleJAAS.config 鈥?This file associates configuration IDs (simple text string) with LoginModules and optional properties.
  • SimpleCallbackHandler.java 鈥?This file implements the CallbackHandler interface and handles the callback events passed by the security service components.
  • SimpleLoginModule.java 鈥?This file implements the LoginModule interface and interfaces between the user and the CallbackHandler to authenticate the user. It uses two arrays to maintain the set of possible usernames and passwords. The passwords are then compared by passing a PasswordCallback instance to the SimpleCallbackHandler and using the readPassword() method defined in the SimpleCallbackHandler class.
  • SimplePrincipal.java 鈥?This file provides a bare-bones implementation of the Principal interface.

    Authorization Files

  • SimpleAuthz.java 鈥?This class is identical to the SimpleAuth.java class in all but one respect. After authenticating the user, it attempts a privileged action. To do this, the code obtains a reference to the current Subject and calls the doAsPrivileged() method from that object reference. We pass the Subject reference and an instance of the SimpleAction class into this method. The Java runtime then will take the supplied Subject reference and attempt to execute the privileged action defined within the run() method of the SimpleAction class.
  • SimpleAction.java 鈥?This class implements the PrivilegedAction interface and defines a single method, run(). It attempts to perform a few actions that are restricted to privileged users (as defined by the policy file). If the Subject has the appropriate privileges to perform these actions, the method will execute without any trouble. Otherwise, it throws an exception.
  • SimpleJAAS.policy 鈥?This file defines the activities for which permission has been granted and which code has permission to perform them (code-level access). These grant statements can further be narrowed to allow only a particular Principal (user-level access).

    To test the application, run the provided script and indicate whether you want to test just authentication ('run auth') or authentication and authorization ('run authz'). When prompted for a username and password, provide any of the following pairs:

  • guest, sesame
  • user1, pass1
  • user2, pass2

    You will receive verbose output if the debug option in the config file debug property is set to 'true'. The output will be limited if it is set to 'false'.



  • my java 2005-08-25 13:43 鍙戣〃璇勮
    ]]>
    Implement Single Sign-on with JAAS http://www.tkk7.com/lmsun/articles/11029.htmlmy javamy javaThu, 25 Aug 2005 05:29:00 GMThttp://www.tkk7.com/lmsun/articles/11029.htmlhttp://www.tkk7.com/lmsun/comments/11029.htmlhttp://www.tkk7.com/lmsun/articles/11029.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11029.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11029.html 
    JAAS is an ideal tool for access control in a multi-user environment where users must be granted varying privileges. Learn how to implement single sign-on for multiple Web applications based on JAAS.  

    With the increasing use of distributed systems, users often need to access multiple resources to finish a single business transaction. Traditionally, users have had to sign on to all these systems, each of which may involve different usernames and authentication requirements. With the introduction of the single sign-on technique, users can login once and be authenticated for all systems involved in a given business transaction.

    Although the single sign-on concept is appealing, implementing it is not at all easy because enterprise systems often have varying security requirements and a wide range of underlying technologies on which they are deployed. In Java environments, Java Authentication and Authorization Service (JAAS) has made implementation easier. JAAS, a significant enhancement to the Java security architecture, is an ideal tool for access control in a multi-user environment where users must be granted varying privileges. Unlike the standard JDK security model, which is code-source-based permission checking, JAAS controls access to resources with both code-source-based and user/role-based permission checking. Most importantly, the "pluggable" and stackable login module architecture that JAAS defines makes it instrumental in supporting legacy security implementations on different technologies and serves as a useful mechanism for implementing single sign-on.

    Single sign-on can be implemented for applications that are deployed either locally or over a network. In the case of a network, after the user logs into the primary domain, an encrypted secure token is created and sent over the wire to other applications. In local networks, user credential data is exchanged directly between applications. Both deployment options share two key challenges: passing user credential information between involved domains and translating this information.

    An enterprise application can be comprised of several Web applications, each of which may depend on different technologies and data stores to retrieve the user information it needs to authenticate the user and determine his or her privilege. If a business transaction crosses the Web application boundary, the user needs to log into each Web application and present similar credentials to each of the application authentication services.

    This article demonstrates a single sign-on implementation for multiple Web applications based on JAAS. Specifically, it introduces an approach to achieving single sign-on between Web applications deployed on the same application server.

    The JAAS Authentication Framework
    Before I get into the single sign-on implementation, let's examine what's under the JAAS hood. The JAAS framework is composed of two interdependent parts: an authentication part and an authorization part. The authentication part is used to determine the identity of the user, while the authorization part checks the permission of the authenticated user and controls resource access based on the user's privileges.

     

    A user has to be authenticated before he/she can access any sensitive resources. After the user is successfully authenticated, his/her principal is populated in the associated Subject class and the permissions granted to the principal are then checked by the authorization component.

    Pluggable Authentication Module (PAM) Framework
    The JAAS authentication framework is based on Pluggable Authentication Module (PAM). JAAS authentication is performed in a pluggable fashion that allows an application to add more authentication modules. Java applications can remain independent from underlying authentication technologies, and thus both legacy and new authentication technologies can be seamlessly configured without requiring modifications to the application itself.

    The JAAS authentication framework allows applications to define any number of login modules in the configuration file. The JAAS framework invokes these login modules in the order they were specified. Applications can also specify a flag to each login module to indicate the relative importance of that module. The overall authentication depends on the combined results of these individual authentication modules.

    PAM allows different Web applications to authenticate users against its own data store, be it an LDAP server, relational database, NT domain, or even a file. PAM is the feature that enables developers to implement single sign-on among Web applications deployed on the same application server.

    LoginModule
    The LoginModule interface gives developers the ability to implement different kinds of authentication technologies that can be plugged under an application. For example, one type of LoginModule may perform a username/password-based form of authentication. Other LoginModules may interface to hardware devices such as smart cards or biometric devices.

    The ability to pass optional share information between login modules is the key feature I employ to achieve single sign-on among Web applications. User credential information can be shared using this option and since it is not sent across the network, there is no need for extra effort to maintain the integrity and security of the credential information.

    JAAS Implementation of Single Sign-On for Multiple Web Apps
    Now let's get to the implementation of single sign-on based on JAAS for Web applications deployed on the same server. To make it easier for discussion, I use an LDAP-based login module as an example.

     

    Login Configuration for Single Sign-On
    When multiple Web applications are deployed on a single application server instance, usually each Web application authenticates users based on its own data store. One Web application may use a relational database to store user security information and another may use an LDAP server to authenticate users. The JAAS PAM architecture allows an enterprise application to define a stack of login modules, each of which is independent and communicates to its own data source. To achieve single sign-on, each Web application defines its own login module and all modules are stacked in a certain order in the login configuration file.

    JAAS defines a configuration interface, which a user can implement to store configuration data in a file or a database. In this discussion, I assume a file-based login configuration and I use a Logistics enterprise application as an example. The Logistics enterprise application contains two Web applications: carrier Web application and shipper Web application. Carrier users log into the carrier Web application to report location and movement events for shipment and Shipper users log into the shipper Web application to query the delivery events of shipment.

    If a 3PL (third-part logistics) uses this Logistics enterprise application, employees of the 3PL will need to log into both Web applications to maintain and query shipment status on behalf of both the carrier and shipper. To achieve single sign-on in this situation based on JAAS, the login configuration file needs to be defined as follows:

    
    LogisticsEnterpriseApplication
    {
       com.cysive.framework.security.ldap.LDAPLoginModule 
    required name=CarrierSecurityDomain; com.cysive.framework.security.ldap.LDAPLoginModule
    required name=ShipperSecurityDomain useSharedState=true; };

    Notice two LDAP login modules are defined: one for the carrier Web application and one for the shipper Web application. These two login modules may communicate to the same LDAP server or different ones, depending on the configuration (using name attribute to link to the particular configuration block) for the LDAP server. For single sign-on, the flags for both login modules are specified as required (other flags include optional, sufficient, and requisite), which means the user must be successfully authenticated by both LDAP servers.

    Additionally, the attribute useSharedState is specified. If it is true, this LoginModule retrieves the username and password from the module's shared state, using "javax.security.auth.login.name" and "javax.security.auth.login.password" as the respective keys. The retrieved values are used for authentication. The username and password are set into shared state by LoginContext before invoking the login method of the login module instance. The useSharedState attribute allows all login modules to share the user's credential information, which is captured only once.

    An XML-based Configuration for Login Module
    When the login module communicates with the data store, be it a database or an LDAP server, it requires certain configurations for common or special attributes. Using the LDAP login module for example, it will at least know the hostname of the LDAP server. Depending on your implementation, you may need different configuration parameters. Listing 1 shows a sample configuration block for the two LDAP login modules defined in the previous sections.

    This configuration needs to be loaded when the application server starts up so it can be shared by Web applications loaded later. I will not discuss each entry in detail but instead focus on the parts that are relevant to single sign-on.

    While each block is being loaded, the initializer class is invoked. The initializer reads all the properties and registers them in the domain manager class with the name specified by the name attribute. The value of this name attribute is the same as the one specified in the login configuration file. This is how the login module entry is associated with its configuration block.

    If the configuration is simple, you can even configure it when you define the login module in the configuration file, such as:

    
    com.cysive.framework.security.ldap.LDAPLoginModule 
    required DriverName="oracle.jdbc.driver.OracleDriver"
    InitialCapacity="0" MaxCapacity="10" Properties="user=cymbio;password=cymbio
    URL="jdbc:oracle:thin:@jtao1:1521:jtao1";

    However, if your initialization for a login module requires substantial setup, a separate initialization block is the preferred approach.

    In the two sample LDAP initialization blocks, the carrier security domain configures the login module to talk to the carrier.cysive.com LDAP server while the shipper login module communicates with shipper.cysive.com. You can easily substitute one of them with a relational database login module if user security information is stored in a database.

    Passing Shared Security Token Between Login Modules
    JAAS defines a LoginContext class, which provides a context for all login modules defined for an application. Its login method iterates through all login modules and calls each login module's login method. It determines the overall authentication result by combining the results of the login method returned from each login module.

    In the login method of LoginContext, each login module defined in the configuration file is instantiated and then is passed four parameters using the initialize method of the login module (See Listing 2, exception checking is omitted for smaller code).

    The following are the four parameters the initialize method passes:

  • Subject is populated with principal and credential information by the login module
  • CallBackHandler is used by the login module for capturing user credential information (such as username/password)
  • Shared state map will be used for passing user security information between login modules
  • Options are additional name/value pairs defined in the configuration file and are meaningful only for that particular login module.

    The shared state map parameter is key to implementing single sign-on. After the first login module captures the user credential information, such as user name and password, it puts the information into the shared state map and passes it to other login modules on the list. The other login module has an optional parameter specified (useSharedState=true), so it simply gets the shared security information back and authenticates against its own security data store. Listing 3 shows a code excerpt for the LoginModule that implements this (exception checking has been omitted to reduce the length of the code segment).

    ReMapping of Security Information
    Using a shared state map to pass security information between login modules to achieve single sign-on requires the user to have the same credential information across all domains. I could enforce the same username and password for all domains that involve single sign-on, but that may limit legacy security systems that have varying user name and password requirements. For example, different authentication mechanisms may have their own distinctive password requirements with regard to length, characters allowed, and so forth. These requirements make using the same username and password for multiple login modules problematic.

    In their paper, "Making Login Services Independent of Authentication Technologies", Vipin Samar and Charlie Lai proposed a mapping mechanism that solves this problem. This mapping enables the user's primary password to be used for encrypting the user's secondary passwords. Once the primary password is verified, the login module obtains the password by decrypting the mechanism-specific encrypted password with the primary password. It then authenticates it to its data store. How the password is encrypted depends completely on the module implementation. To use password mapping, Samar and Lai also suggest two more optional attributes be passed to the login module:

  • use_mapped_pass - Use the password-mapping scheme to get the actual password for this module. The module should not ask for the password if the user cannot be authenticated by the first password. Note that the process for decrypting passwords is left completely to the module.
  • try_mapped_pass - This attribute is the same as use_mapped_pass, except that if the primary password is not valid, the module should prompt the user for it.

    Shared Map Is Key
    Single sign-on for multiple Web applications is useful when business transactions cross session context boundaries. The pluggable and stackable login module infrastructure provided by JAAS allows enterprise applications to authenticate users with different login mechanisms and technologies. Exchanging security information between login modules using the shared map is the key to implementing single sign-on.



  • my java 2005-08-25 13:29 鍙戣〃璇勮
    ]]>
    Cross-Domain Single Sign-On Authentication with JAAS http://www.tkk7.com/lmsun/articles/11028.htmlmy javamy javaThu, 25 Aug 2005 05:23:00 GMThttp://www.tkk7.com/lmsun/articles/11028.htmlhttp://www.tkk7.com/lmsun/comments/11028.htmlhttp://www.tkk7.com/lmsun/articles/11028.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11028.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11028.html
    Cross-Domain Single Sign-On Authentication with JAAS

    Leverage your existing JAAS enterprise security system to provide SSO across multiple subsystems. Implementing this J2EE security model will take your security architecture to the next level. 
    ingle sign-on (SSO) is a very hot topic. Businesses in every industry are eager to integrate legacy systems into newer applications, and SSO can alleviate the headaches users experience when trying to manage a long list of user names and passwords for various systems. Enter the Java Authentication and Authorization Service (JAAS).

    As I wrote in a DevX 10-Minute Solution, "JAAS Security in Action": JAAS 鈥渋s a flexible, standardized API that supports runtime pluggability of security modules.鈥?If you are unfamiliar with JAAS, I recommend reading that article and reviewing the downloadable code before continuing, as this article assumes an understanding of JAAS. It takes the next logical step from a security architecture standpoint: integrating your J2EE security model to provide SSO across multiple subsystems by leveraging your existing LDAP directory server, database server, or any other enterprise security system.

    Before going any further, let's clarify how this article uses the term "domain": It refers to security domains (LDAP, database, etc.) and not Web domains. If you are interested in using JAAS to share authentication information between multiple Web applications, read the article "Implement Single Sign-on with JAAS" written by James Tao in October of 2002. Additionally, if you are interested in Web applications that exist across firewalls and participate in some sort of Web service exchange, read the joint Web Single Sign-On Identify specifications that Microsoft and Sun recently published.

    Securing the Enterprise

    Single sign-on allows users to enter security credentials once (typically by logging into a workstation or a Web application) and have those credentials propagated to each local and network application the user accesses during his or her session. Local applications exchange authentication information directly, while remote network applications exchange authentication information across the network via encrypted security tokens.

    Regardless of whether the deployment scenario is local, across a network, or a combination of the two, the security challenges are the same: sharing credentials between domains, correctly interpreting the credentials once received, and managing different sets of privileges across these domains (e.g., a user could be a manager within one system, a power user in another system, and a normal user in a third).

    Finally, the heterogeneous nature of most enterprise systems creates some unique challenges for SSO security architectures. Each application within the enterprise could be comprised of different technologies, operate on different platforms, access disparate data sources, and except slightly different authentication credentials for the same principal (user). In spite of these overwhelming obstacles, JAAS combined with LDAP provides a solid framework for designing and implementing a robust SSO enterprise security framework.



    The Architecture

    The backbone of a J2EE SSO architecture is the standard J2EE security model, which is well documented in other places (see Related Resources in the left-hand column). In a nutshell, J2EE security consists of principals (users) who are associated with roles (groups) that are given privileges (authorization). These roles with assigned privileges are further organized under the concept of a realm (domain). Each realm maps users and groups to privileges within its own scope. The key to providing SSO is seamlessly connecting these different realms (and corresponding enterprise systems) without requiring the user to enter authentication information each time he or she wishes to access another system.

    Consider the following example: A user logs in to an application via HTTP, authenticating herself against the server's security realm (MemoryRealm, JDBCRealm, JAASRealm, etc). The user then uses the Web application's search feature, querying the database and returning a resultlist. The database could then require that the middleware platform authenticate against the DB before performing the transaction. Finally, the user wants to update information stored in her directory server (LDAP). This is a privileged action, requiring the user to first authenticate against the LDAP realm before modifying any directory data. All three of these realms likely require slightly different authentication schemes (different user IDs, passwords, additional security tokens, etc.), but the same principal (user) is accessing them each time.

    Java can provide an elegant SSO solution for the above scenario (and any number of similar scenarios) using JAAS's pluggable login module architecture. JAAS login modules facilitate the smooth integration of J2EE's security framework with various systems and their respective heterogeneous authentication mechanisms (OS, LDAP, database, etc.). These modules can be configured to share authentication data and designed to correctly identify users and roles by mapping principals and roles鈥攅ven across domains with differing security schemas.

    The Components

    The application components required for a JAAS SSO solution include the following:
    • Two or more enterprise systems that need a common, integrated security framework
    • Two or more JAAS login module classes to drive the authentication exchange between agent (user or subsystem) and callback handler
    • One or more JAAS callback handler classes to respond to callback events in order to perform the actual authentication procedure(s)
    • A login configuration file to define how JAAS will manage authentication across multiple security realms (configuration could even be stored in an XML file or database)

    Assembling these components and connecting all of the pieces correctly can be a bit daunting the first time. Be sure to thoroughly test your JAAS authentication components individually with each system prior to attempting to link them and share authentication information. The process of packaging, deploying, and testing your solution should go something like this:

    1. Write a login module (implement LoginModule, a subtype of LoginContext) and a callback handler (implement CallbackHandler interface) for authenticating against a single enterprise system (LDAP, database, etc.).
    2. Define the configuration for your login module (this could be as simple as an XML file containing a single statement).
    3. Define a UI (Web, console, or rich GUI) to capture authentication data, and then pass it to your login module.
    4. If this is a server-based solution (HTTP, sockets, RMI, etc.), define the J2EE security (constraints and roles) on the server in the usual way (web.xml or application.xml), and then define a realm on the server (server.xml) that references the JAAS login module configuration (accomplished via the appName attribute). Local (non-server) solutions will simply rely upon JAAS and a J2SE policy file to define security constraints and permissions.
    5. Start the server (specifying the login configuration file via a Java command line attribute), launch the client, and provide authentication credentials. Debug and modify as necessary to resolve any errors.
    6. Rinse and repeat. Continue this process as necessary until each enterprise system can successfully be authenticated via a JAAS login module.
    7. Finally, hook all of the individual authentication pieces together. The following section addresses this issue.

    The above list simply gives you a brief overview of the process. For more details on how to actually accomplish these steps, please consult the links in the Related Resources space.



    Sharing Authentication Across Domains

    The JAAS configuration file mentioned earlier defines configuration IDs, which contain one or more LoginModule definitions and corresponding attributes. The key to sharing authentication information across security domains is to have a single JAAS configuration ID that lists multiple login modules, with the second, third, and following modules specifying the useSharedState attribute as true (allowing security credentials to be shared).

    The following is a sample configuration involving two systems, LDAP and an Oracle database, included within the same SSO architecture:

    
    BasicAuth {
    	com.xyz.ldap.LDAPLoginModule 
    required name=LDAPSecurityDomain;
    };
    
    DBAccessAuth {
    	com.xyz.ldap.LDAPLoginModule 
    required name=LDAPSecurityDomain;
    com.xyz.db.OracleLoginModule
    required name=OracleSecurityDomain
    useSharedState=true;
    };
    

    Two configurations are defined (BasicAuth and DBAccessAuth) to provide the flexibility of authenticating a user against one or both systems.

    To implement this, the first system (LDAP) is treated as the primary system. The corresponding login module should be setup as the security realm for the J2EE container (using the BasicAuth configuration). Once a user has authenticated against the primary system (see Figure 1), she can have her security credentials propagated to the other system(s) in the chain (using the DBAccessAuth) that require authenticated access (see Figure 2).

    Click to enlarge
    Figure 1: Initial System Authentication/Authorization Process Through JAAS

    Click to enlarge
    Figure 2: Subsequent System Authentication/Authorization Process Through JAAS

    This simple example contains only two subsystems, but a more complex system could include as many JAAS login modules as systems that need to share security credentials. The key difference between how authentication occurs with the two subsystems is that the primary system has JAAS authentication handled automatically (the container manages the process since the login module is configured as a security realm). The secondary subsystem (as well as any subsequent systems) must be called programmatically via the login() method of LoginContext:

    
    LoginContext ctx = new LoginContext( "DBAccessAuth", new SimpleCallbackHandler() );
    

    The above example assumed a fairly ideal situation in which the user's security credentials were the same for both subsystems. In real life, this is rarely the case. You often find yourself needing to integrate legacy systems with new applications, each requiring different credentials. You can accomplish this by using the original authentication information to unlock a secured datastore that houses secondary authentication information for the specified principal (one or more sets of credentials). Once you've obtained this other authentication information, you then can use it to authenticate transparently against any secondary systems. (For more details on this approach, read Vipin Samar and Charlie Lai's article (PDF): "Making Login Services Independent of Authentication Technologies".)

    Voila! Single sign-on across multiple security domains by mapping primary credentials gathered from the user to secondary credentials stored on the server and used to authenticate transparently against other enterprise systems.

    Single SSO in Your Enterprise Framework

    SSO is a popular feature of modern enterprise systems. Unfortunately, implementing SSO can be difficult and error-prone. This brief article provides a high-level overview and guide for architects, developers, and/or managers who are interested in implementing a SSO security architecture within their current enterprise frameworks.

    Kyle Gabhart is a Senior Principal Information Systems Architect with L-3 Communications, Link Simulation and Training Division. Author of dozens of articles and books, Kyle has served as a consultant, trainer, and mentor for Fortune 500 companies, including American Express, J.P. Morgan-Chase, Goldman Sachs, and Verizon. Find Kyle on the Web at http://www.gabhart.com and reach him by email at rkgabhart@link.com.



    my java 2005-08-25 13:23 鍙戣〃璇勮
    ]]>
    JCIFS NTLM HTTP Authenticationhttp://www.tkk7.com/lmsun/articles/10585.htmlmy javamy javaSat, 20 Aug 2005 05:45:00 GMThttp://www.tkk7.com/lmsun/articles/10585.htmlhttp://www.tkk7.com/lmsun/comments/10585.htmlhttp://www.tkk7.com/lmsun/articles/10585.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10585.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10585.htmlNtlmSsp classes directly. This Filter scales very well primarily because sessions are multiplexed over transports. But this functionality is not without caveats. Note: This functionality is a non-conformant extension to HTTP conceived entirely by Microsoft. It inappropriately uses HTTP headers and therefore may not work with all Servlet containers or may stop working with a new release of your application server. Also, this flavor of password encryption is not very secure so under no circumstances should it be used to authenticate clients on the Internet.

    Note: Don't forget to restart the container after changing jCIFS init-parameters. JCIFS must use the container class loader and jCIFS properties are only read once when jCIFS classes are initialized.

    Installation and Setup

    Put the latest jCIFS jar file in the lib/ directory of your webapp [1]. Because jCIFS properties are loaded once when the jCIFS classes are first accessed, it is necessary to actually stop and restart the container if any jCIFS properties have been changed. Below are two web.xml configurations. Note that the jcifs.smb.client.domain and jcifs.smb.client.domainController properties are mutually exclusive.

    Production web.xml Example

    A minimalistic web.xml file with filter and filter-mapping directives might look like the following:
    <filter>
        <filter-name>NtlmHttpFilter</filter-name>
        <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
    
        <init-param>
            <param-name>jcifs.smb.client.domain</param-name>
            <param-value>NYC-USERS</param-value>
        </init-param>
        <init-param>
            <param-name>jcifs.netbios.wins</param-name>
            <param-value>10.169.10.77,10.169.10.66</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>NtlmHttpFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    This filter section illustrates the setup for authenticating clients against the domain NYC-USERS. This is suitable for large numbers of concurrent users as jCIFS will cycle through domain controllers and use an alternate WINS server if necessary.

    The above will authenticate users accessing all content against the domain NYC-USERS. The WINS server 10.169.10.77 will be queried to resolve NYC-USERS to an IP address of a domain controller. If that WINS server is not responding, 10.169.10.66 will be queried.

    Alternate web.xml Example

    The below example filter section illistrates how to specify the IP address of the domain controller specifically using the jcifs.http.domainController property. The target machine does not need to be a real domain controller -- it could be just a workstation. Also illustrated below is the jcifs.smb.client.logonShare property. This will cause jCIFS to attempt to access the resource \\192.168.2.15\JCIFSACL when authenticating users. By creating that share and changing the Access Control List only certain users or groups of users will have access to your website.
    <filter>
        <filter-name>NtlmHttpFilter</filter-name>
        <filter-class>jcifs.http.NtlmHttpFilter</filter-class>
    
        <init-param>
            <param-name>jcifs.http.domainController</param-name>
            <param-value>192.168.2.15</param-value>
        </init-param>
        <init-param>
            <param-name>jcifs.smb.client.logonShare</param-name>
            <param-value>JCIFSACL</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>NtlmHttpFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    This filter section illustrates the setup for authenticating against a JCIFSACL share for testing or a site with a small number of concurrent users (e.g. 1000)

    Either a jcifs.smb.client.domain or jcifs.smb.client.domainController property is required. This will be suitable to authenticate clients that are members of the specified domain as well as other domains with which it has trusts relationships.

    Running the NtlmHttpAuthExample.java example should be a suitable test of the Filter.

    NTLM HTTP Authentication Example

    NYC-USERS\MIALLEN successfully logged in

    Please submit some form data using POST

    field1 = hello
    The significance of the POST test is that after negotiating NTLM HTTP Authentication once, IE will not POST any form data until it has negotiated the password hashes again.

    If the NTLM HTTP Authentication Filter is not enabled something like the following will be displayed:
    null successfully logged in
    Notice the user was permitted access. Unlike this example, developers might add an additional check to make sure getRemoteUser does not return null.

    Non MSIE Clients and "Basic" Authentication

    NTLM HTTP authentication is only supported by MSIE transparently. Mozilla 1.6 supports NTLM HTTP negotiation but it will always prompt the user for credentials by default (although the Mozilla documentation on Integrated Authentication describes how to make it transparent to the user for trusted sites). For other clients it is possible to use basic authentication to pass NTLM password credentials. This is strongly discouraged if SSL is not being used because it sends these credentials in plain text. It would not be difficult for another user to download and install a program to "snoop" LAN traffic and obtain other user's passwords.

    Regardless, this functionality has been added to the NtlmHttpFilter and NtlmServlet (for pre 2.3 servlet containers) although it is disabled by default. To enable this capability set the jcifs.http.basicRealm, jcifs.http.enableBasic, and jcifs.http.insecureBasic properties described in the table below.

    JCIFS Properties Meaningful to NTLM HTTP Authentication

    All parameters that begin with 'jcifs.' will be set as jCIFS properties which means that any jCIFS properties may be used as init parameters. These properties must be set before jCIFS classes are used. For a complete list of jCIFS properties refer to the overview page of the API documentation. Here is a select subset of jCIFS properties with additional notes in the context of NTLM HTTP Authentication.

    jcifs.smb.client.domain The NT domain against which clients should be authenticated. Generally it is necessary to also set the jcifs.netbios.wins parameter or a domain controller may not be found. This parameter will be ignored for NTLM HTTP authentication purposes if a jcifs.http.domainController property is specified (although they can be used together for "preauthenctication" as described in the SMB Signatures and Windows 2003 section below).
    jcifs.http.domainController The IP address of any SMB server that should be used to authenticate HTTP clients with the NtlmHttpFilter class. If this is not specified the jcifs.smb.client.domain 0x1C NetBIOS group name will be queried. If these queries fail an UnknownHostException will be thrown. It is not necessary for this to specify a real domain controller. The IP address of a workstation will do for simple purposes.
    jcifs.http.basicRelm The realm for basic authentication. This property defaults to 'jCIFS'.
    jcifs.http.enableBasic Setting this property to true enables basic authentication over HTTPS only.
    jcifs.http.insecureBasic Setting this property to true enables basic authentication over plain HTTP. This configuration passes user credentials in plain text over the network. It should not be used in environment where security is required.
    jcifs.http.loadBalance If a jcifs.smb.client.domain property is specified (and domainController is not specified) the NtlmHttpFilter will query for domain controllers by name. If this property is true the Filter will rotate through the list of domain controllers when authenticating users. The default value is true. The jcifs.netbios.lookupRespLimit property can also be used to limit the number of domain controllers used.
    jcifs.netbios.lookupRespLimit The 0x1C NetBIOS name query returns a list of domain controllers. It is believed that the servers at the top of this list should be favored. This property limits the range of servers returned by name queries. The default value is 5 meaning the top 5 domain controllers will be used.
    jcifs.netbios.wins The IP address of the WINS server. This is required when accessing hosts on different subnets (like a domain controller by name) and it is highly recommended if a wins server is available.
    jcifs.smb.client.laddr The ip address of the local interface the client should bind to if it is different from the default. For example if jCIFS is used to authenticate clients on one interface and the domain controller for those clients is accessible only on another interface of a webserver with two NICs it may be necessary to specify which interface jCIFS should use.
    jcifs.netbios.laddr The ip address of the local interface the client should bind to for name queries if it is different from the default. Likely set to the same as the above property.
    jcifs.smb.client.attrExpirationPeriod Attributes of a file are cached for attrExpirationPeriod milliseconds. The default is 5000 but the NetworkExplorer servlet will attempt to set this property to 120000. Otherwise, when listing large directories, the attributes of SmbFiles may expire within the default period resulting in a large number of additional network messages and severe performance degradation.
    jcifs.smb.client.soTimeout To prevent the client from holding server resources unnecessarily, sockets are closed after this time period if there is no activity. This time is specified in milliseconds. The default is 15000 however when NTLM HTTP Authentication is used, the NtlmHttpFilter will attempt to set this value to 5 minutes so that frequent calls to SmbSession.logon() do not provoke redundant messages being submitted to the domain controller. If it is not desirable to cache password hashes set this value back to 15000.
    jcifs.netbios.cachePolicy When a NetBIOS name is resolved with the NbtAddress class it is cached to reduce redundant name queries. This property controls how long, in seconds, these names are cached. The default is 30 seconds, 0 is no caching, and -1 is forever. When NTLM HTTP Authentication is used, NtlmHttpFilter will attempt to set this value to 20 minutes so that frequent queries for a domain controller will be cached.

    Must Restart The Container

    If you change any jcifs properties or replace an existing jcifs jar file with a different one, the container must be restarted. This is because most jcifs properties are retrieved only once when classes are first loaded.

    Tomcat

    Tomcat requires that all filter directives be adjacent to one another, all filter-mapping directives appear adjacent to one another, all servlet directives ... and so on. This is because Tomcat validates the web.xml against the deployment descriptor DTD.

    MalformedURLException: unknown protocol: smb

    If you get the following exception try upgrading to jcifs-0.7.0b12 or later. Also read the FAQ.
    Exception MalformedURLException: unknown protocol: smb
          at java.net.URL.(URL.java:480)
          at java.net.URL.(URL.java:376)
          at java.net.URL.(URL.java:330)
          at jcifs.smb.SmbFile.(SmbFile.java:355)
          ...
    

    Transparent Authentication and the Network Password Dialog

    If the Filter is working properly the Network Password Dialog should never appear. However there are several requirements that must be met for a web browser to transparently negotiate credentials using NTLM HTTP authenication. If any of these requirements are not met, the default behavior is to present the user with the Network Password dialog. The requirements are:

    1. The client must be logged into the Windows NT domain identified by the jcifs.smb.client.domain parameter (or the domain of the host identified by the jcifs.smb.client.domainController parameter if it is used instead). The client may also be logged into a domain that has a trust relationship with the target domain. Indeed it is not uncommon to configure workstations to join a different domain from those of users. Note that Windows 95/98/ME systems cannot really join a domain but can be configured to do so enough to participate in transparent NTLM HTTP authentication.
    2. Only Internet Explorer will negotiate NTLM HTTP authentication transparently. Mozilla will always prompt the user for credentials (someone please notify us when/if this is not true anymore). At the time this FAQ was written it was not known which other browsers, if any, can negotiate NTLM HTTP authenication transparently.
    3. Either the target URL must contain a server in the local domain (e.g. ws1.mycompany.com) or the client's security settings must be changed (e.g. Tools > Internet Options > Security > Local Intranet > Sites > Advanced > add your site). If the URL does not contain a URL in the defined IntrAnet zone (e.g. not an IP address), Internet Explorer will assume that the server is in the IntErnet zone and present the user with the Network Password dialog. It would be very bad if a server on the Internet could convince IE to send it your NTLM password hashes. These hashes are easily cracked with brute force dictionary attacks. To prevent this scenario, IE tries to distinguish between Intranet sites and Internet sites. Here are some important notes to consider when deploying a site with NTLM HTTP Authentication regardless of whether or not jCIFS is used to do it.
    4. The user's credentials must be valid. For example if the account has expired, been disabled or is locked out the Network Password dialog will appear. To determine which error was at fault it will be necessary to modify the NtlmHttpFilter to inspect the SmbAuthException in doFilter.
    5. The jCIFS client must support the lmCompatibility level necessary for communication with the domain controller. If the server does not permit NTLMv1 try to set jcifs.smb.lmCompatibility = 3.

    Personal Workstation AD Security Policy

    If your Active Directory security policy requires that users only log into the domain from their personal workstations JCIFS will fail to authenticate and the server security log will have entries like "\\JCIFS10_40_4A cannot be authorized". This occurs because the domain controller is failing to resolve the dynamically generated "calling name" submitted by the client during protocol negotiation. To get around this it is necessary to set the jcifs.netbios.hostname property to a valid NetBIOS name that can be resolved by the NetBIOS name service (e.g. WINS) and add that name to the AD security policy as a permitted client.

    For example, you can set this property using an init-paremeter in the web.xml file for the NTLM HTTP filter as follows:
    <init-parameter>
        <parameter-name>jcifs.netbios.hostname</parameter-name>
        <parameter-value>MYHOSTNAME</parameter-value>
    </init-parameter>
    

    HTTP POST and Protecting Sub-Content

    Once IE has negotiated NTLM HTTP authentication it will proactively renegotiate NTLM for POST requests for all content associated with the server (based on IP?). Therefore when using HTTP POST requests it is not possible to restrict access to some content on the server as IE will attempt and fail to negotiate NTLM (standard IE error page?). This is a protocol limitation and there does not appear to be a way to convince IE to stop proactively negotiating for POST requests once it has been determined that the server is capable of negotiating NTLM authentication.

    SMB Signatures and Windows 2003

    If the domain controller against which you are authenticating clients requires SMB signatures (Windows 2003 does by default), it is recommended that you provide init-parameters for the jcifs.smb.client.{domain,username,password} to perform "preauthentication" for each transport to a domain contoller so that a proper SMB signing key will be generated. In fact, this may be necessary for proper operation; it has been observed that NT 4.0 does not check the signatures of authentication requests but the behavior has not been confirmed in all environments. If the Filter works for the first authentication but fails with a second user shortly thereafter this would suggest that signing was established but subsequent authentications are failing due to the lack of a good signing key. Additionally, without a proper signing key certain requests (SMB_COM_TREE_DISCONNECT and SMB_COM_LOGOFF_ANDX) will cause signature verification failures (although they are harmless to the client).

    A third solution for signature issues is to change the jcifs.smb.client.ssnLimit to 1. This will require that every authentication uses a separate transport. Because the MAC signing key is only used on SMB communication occuring after the initial authentication, signing will be effectively ignored. However, this solution will significantly reduce scalability as each authentication will open it's own transport. For this reason the second solution of using a "workstation account" to preauthenticate transports is considered the superior method and should be used by default for servers that requires signatures.

    NTLM HTTP Authentication Protocol Details

    The NTLM HTTP Authentication process is described well in these documents:

    http://davenport.sourceforge.net/ntlm.html
    http://www.innovation.ch/java/ntlm.html

    The process can be summarized as a 3 request/response "handshake". So doGet() will be called three times. The first is the initial request. A 401 Unauthorized is sent back to which IE submits a special message encoded in a header. Another 401 Unauthorized is sent back after which IE submits the password hashes. This is where jCIFS comes in. The password hashes alone are useless. You must check their authenticity against the password database on a server somewhere (actually you can specify the IP of a plain workstation or any other SMB server). Otherwise a user who's workstation is not a member of the domain will get a password dialog into which they could put anything and it would let them in. This is what pretty much all the examples seen in various forums do. Don't be fooled.

    [1] Due to restrictions in how protocol handlers are loaded, if the SMB URL protocol handler is to be used (meaning you want to access SMB resources with smb:// URLs) within your application it is necessary for the jCIFS jar to be loaded by the System class loader. This can usually be achived by placing it in the container lib/ directory. However, for containers that load servlet classes in a child classloaders (Tomcat) this too will cause problems as jCIFS will not be able to load javax.servlet.* classes. To get the filter and the URL protocol handler to operate together requires some experimentation and depends on the container being used.

    my java 2005-08-20 13:45 鍙戣〃璇勮
    ]]>
    NTLM Authentication Scheme for HTTPhttp://www.tkk7.com/lmsun/articles/10507.htmlmy javamy javaFri, 19 Aug 2005 05:54:00 GMThttp://www.tkk7.com/lmsun/articles/10507.htmlhttp://www.tkk7.com/lmsun/comments/10507.htmlhttp://www.tkk7.com/lmsun/articles/10507.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10507.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10507.htmlIntroduction

    This is an attempt at documenting the undocumented NTLM authentication scheme used by M$'s browsers, proxies, and servers (MSIE and IIS); this scheme is also sometimes referred to as the NT challenge/response (NTCR) scheme. Most of the info here is derived from three sources (see also the Resources section at the end of this document): Paul Ashton's work on the NTLM security holes, the encryption documentation from Samba, and network snooping. Since most of this info is reverse-engineered it is bound to contain errors; however, at least one client and one server have been implemented according to this data and work successfully in conjunction with M$'s browsers, proxies and servers.

    Note that this scheme is not as secure as Digest and some other schemes; it is slightly better than the Basic authentication scheme, however.

    Also note that this scheme is not an http authentication scheme - it's a connection authentication scheme which happens to (mis-)use http status codes and headers (and even those incorrectly).

    NTLM Handshake

    When a client needs to authenticate itself to a proxy or server using the NTLM scheme then the following 4-way handshake takes place (only parts of the request and status line and the relevant headers are shown here; "C" is the client, "S" the server):

        1: C  --> S   GET ...
        
        2: C <--  S   401 Unauthorized
                      WWW-Authenticate: NTLM
        
        3: C  --> S   GET ...
                      Authorization: NTLM <base64-encoded type-1-message>
        
        4: C <--  S   401 Unauthorized
                      WWW-Authenticate: NTLM <base64-encoded type-2-message>
        
        5: C  --> S   GET ...
                      Authorization: NTLM <base64-encoded type-3-message>
        
        6: C <--  S   200 Ok
    

    Messages

    The three messages sent in the handshake are binary structures. Each one is described below as a pseudo-C struct and in a memory layout diagram. byte is an 8-bit field; short is a 16-bit field. All fields are unsigned. Numbers are stored in little-endian order. Struct fields named zero contain all zeroes. An array length of "*" indicates a variable length field. Hexadecimal numbers and quoted characters in the comments of the struct indicate fixed values for the given field.

    The field flags is presumed to contain flags, but their significance is unknown; the values given are just those found in the packet traces.

    Type-1 Message

    This message contains the host name and the NT domain name of the client.

        struct {
            byte    protocol[8];     // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
            byte    type;            // 0x01
            byte    zero[3];
            short   flags;           // 0xb203
            byte    zero[2];
    
            short   dom_len;         // domain string length
            short   dom_len;         // domain string length
            short   dom_off;         // domain string offset
            byte    zero[2];
    
            short   host_len;        // host string length
            short   host_len;        // host string length
            short   host_off;        // host string offset (always 0x20)
            byte    zero[2];
    
            byte    host[*];         // host string (ASCII)
            byte    dom[*];          // domain string (ASCII)
        } type-1-message
    
                     0       1       2       3
                 +-------+-------+-------+-------+
             0:  |  'N'  |  'T'  |  'L'  |  'M'  |
                 +-------+-------+-------+-------+
             4:  |  'S'  |  'S'  |  'P'  |   0   |
                 +-------+-------+-------+-------+
             8:  |   1   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            12:  | 0x03  | 0xb2  |   0   |   0   |
                 +-------+-------+-------+-------+
            16:  | domain length | domain length |
                 +-------+-------+-------+-------+
            20:  | domain offset |   0   |   0   |
                 +-------+-------+-------+-------+
            24:  |  host length  |  host length  |
                 +-------+-------+-------+-------+
            28:  |  host offset  |   0   |   0   |
                 +-------+-------+-------+-------+
            32:  |  host string                  |
                 +                               +
                 .                               .
                 .                               .
                 +             +-----------------+
                 |             | domain string   |
                 +-------------+                 +
                 .                               .
                 .                               .
                 +-------+-------+-------+-------+
    
    The host and domain strings are ASCII (or possibly ISO-8859-1), are uppercased, and are not nul-terminated. The host name is only the host name, not the FQDN (e.g. just "GOOFY", not "GOOFY.DISNEY.COM"). The offsets refer to the offset of the specific field within the message, and the lengths are the length of specified field. For example, in the above message host_off = 32 and dom_off = host_off + host_len. Note that the lengths are included twice (for some unfathomable reason).

    Type-2 Message

    This message contains the server's NTLM challenge.

        struct {
            byte    protocol[8];     // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
            byte    type;            // 0x02
            byte    zero[7];
            short   msg_len;         // 0x28
            byte    zero[2];
            short   flags;           // 0x8201
            byte    zero[2];
    
            byte    nonce[8];        // nonce
            byte    zero[8];
        } type-2-message
    
                     0       1       2       3
                 +-------+-------+-------+-------+
             0:  |  'N'  |  'T'  |  'L'  |  'M'  |
                 +-------+-------+-------+-------+
             4:  |  'S'  |  'S'  |  'P'  |   0   |
                 +-------+-------+-------+-------+
             8:  |   2   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            12:  |   0   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            16:  |  message len  |   0   |   0   |
                 +-------+-------+-------+-------+
            20:  | 0x01  | 0x82  |   0   |   0   |
                 +-------+-------+-------+-------+
            24:  |                               |
                 +          server nonce         |
            28:  |                               |
                 +-------+-------+-------+-------+
            32:  |   0   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            36:  |   0   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
    
    The nonce is used by the client to create the LanManager and NT responses (see Password Hashes). It is an array of 8 arbitrary bytes. The message length field contains the length of the complete message, which in this case is always 40.

    Type-3 Message

    This message contains the username, host name, NT domain name, and the two "responses".

        struct {
            byte    protocol[8];     // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
            byte    type;            // 0x03
            byte    zero[3];
    
            short   lm_resp_len;     // LanManager response length (always 0x18)
            short   lm_resp_len;     // LanManager response length (always 0x18)
            short   lm_resp_off;     // LanManager response offset
            byte    zero[2];
    
            short   nt_resp_len;     // NT response length (always 0x18)
            short   nt_resp_len;     // NT response length (always 0x18)
            short   nt_resp_off;     // NT response offset
            byte    zero[2];
    
            short   dom_len;         // domain string length
            short   dom_len;         // domain string length
            short   dom_off;         // domain string offset (always 0x40)
            byte    zero[2];
    
            short   user_len;        // username string length
            short   user_len;        // username string length
            short   user_off;        // username string offset
            byte    zero[2];
    
            short   host_len;        // host string length
            short   host_len;        // host string length
            short   host_off;        // host string offset
            byte    zero[6];
    
            short   msg_len;         // message length
            byte    zero[2];
    
            short   flags;           // 0x8201
            byte    zero[2];
    
            byte    dom[*];          // domain string (unicode UTF-16LE)
            byte    user[*];         // username string (unicode UTF-16LE)
            byte    host[*];         // host string (unicode UTF-16LE)
            byte    lm_resp[*];      // LanManager response
            byte    nt_resp[*];      // NT response
        } type-3-message
    
                     0       1       2       3
                 +-------+-------+-------+-------+
             0:  |  'N'  |  'T'  |  'L'  |  'M'  |
                 +-------+-------+-------+-------+
             4:  |  'S'  |  'S'  |  'P'  |   0   |
                 +-------+-------+-------+-------+
             8:  |   3   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            12:  |  LM-resp len  |  LM-Resp len  |
                 +-------+-------+-------+-------+
            16:  |  LM-resp off  |   0   |   0   |
                 +-------+-------+-------+-------+
            20:  |  NT-resp len  |  NT-Resp len  |
                 +-------+-------+-------+-------+
            24:  |  NT-resp off  |   0   |   0   |
                 +-------+-------+-------+-------+
            28:  | domain length | domain length |
                 +-------+-------+-------+-------+
            32:  | domain offset |   0   |   0   |
                 +-------+-------+-------+-------+
            36:  |  user length  |  user length  |
                 +-------+-------+-------+-------+
            40:  |  user offset  |   0   |   0   |
                 +-------+-------+-------+-------+
            44:  |  host length  |  host length  |
                 +-------+-------+-------+-------+
            48:  |  host offset  |   0   |   0   |
                 +-------+-------+-------+-------+
            52:  |   0   |   0   |   0   |   0   |
                 +-------+-------+-------+-------+
            56:  |  message len  |   0   |   0   |
                 +-------+-------+-------+-------+
            60:  | 0x01  | 0x82  |   0   |   0   |
                 +-------+-------+-------+-------+
            64:  | domain string                 |
                 +                               +
                 .                               .
                 .                               .
                 +           +-------------------+
                 |           | user string       |
                 +-----------+                   +
                 .                               .
                 .                               .
                 +                 +-------------+
                 |                 | host string |
                 +-----------------+             +
                 .                               .
                 .                               .
                 +   +---------------------------+
                 |   | LanManager-response       |
                 +---+                           +
                 .                               .
                 .                               .
                 +            +------------------+
                 |            | NT-response      |
                 +------------+                  +
                 .                               .
                 .                               .
                 +-------+-------+-------+-------+
    

    The host, domain, and username strings are in Unicode (UTF-16, little-endian) and are not nul-terminated; the host and domain names are in upper case. The lengths of the response strings are 24.

    Password Hashes

    To calculate the two response strings two password hashes are used: the LanManager password hash and the NT password hash. These are described in detail at the beginning of the Samba ENCRYPTION.html document. However, a few things are not clear (such as what the magic constant for the LanManager hash is), so here is some almost-C code which calculates the two responses. Inputs are passw and nonce, the results are in lm_resp and nt_resp.

        /* setup LanManager password */
    
        char  lm_pw[14];
        int   len = strlen(passw);
        if (len > 14)  len = 14;
    
        for (idx=0; idx<len; idx++)
            lm_pw[idx] = toupper(passw[idx]);
        for (; idx<14; idx++)
            lm_pw[idx] = 0;
    
    
        /* create LanManager hashed password */
    
        unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
        unsigned char lm_hpw[21];
        des_key_schedule ks;
    
        setup_des_key(lm_pw, ks);
        des_ecb_encrypt(magic, lm_hpw, ks);
    
        setup_des_key(lm_pw+7, ks);
        des_ecb_encrypt(magic, lm_hpw+8, ks);
    
        memset(lm_hpw+16, 0, 5);
    
    
        /* create NT hashed password */
    
        int   len = strlen(passw);
        char  nt_pw[2*len];
        for (idx=0; idx<len; idx++)
        {
            nt_pw[2*idx]   = passw[idx];
            nt_pw[2*idx+1] = 0;
        }
    
        unsigned char nt_hpw[21];
        MD4_CTX context;
        MD4Init(&context);
        MD4Update(&context, nt_pw, 2*len);
        MD4Final(nt_hpw, &context);
    
        memset(nt_hpw+16, 0, 5);
    
    
        /* create responses */
    
        unsigned char lm_resp[24], nt_resp[24];
        calc_resp(lm_hpw, nonce, lm_resp);
        calc_resp(nt_hpw, nonce, nt_resp);
    

    Helpers:

        /*
         * takes a 21 byte array and treats it as 3 56-bit DES keys. The
         * 8 byte plaintext is encrypted with each key and the resulting 24
         * bytes are stored in the results array.
         */
        void calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
        {
            des_key_schedule ks;
    
            setup_des_key(keys, ks);
            des_ecb_encrypt((des_cblock*) plaintext, (des_cblock*) results, ks, DES_ENCRYPT);
    
            setup_des_key(keys+7, ks);
            des_ecb_encrypt((des_cblock*) plaintext, (des_cblock*) (results+8), ks, DES_ENCRYPT);
    
            setup_des_key(keys+14, ks);
            des_ecb_encrypt((des_cblock*) plaintext, (des_cblock*) (results+16), ks, DES_ENCRYPT);
        }
    
    
        /*
         * turns a 56 bit key into the 64 bit, odd parity key and sets the key.
         * The key schedule ks is also set.
         */
        void setup_des_key(unsigned char key_56[], des_key_schedule ks)
        {
            des_cblock key;
    
            key[0] = key_56[0];
            key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
            key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
            key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
            key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
            key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
            key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
            key[7] =  (key_56[6] << 1) & 0xFF;
    
            des_set_odd_parity(&key);
            des_set_key(&key, ks);
        }
    

    Keeping the connection alive

    As mentioned above, this scheme authenticates connections, not requests. This manifests itself in that the network connection must be kept alive during the second part of the handshake, i.e. between the receiving of the type-2 message from the server (step 4) and the sending of the type-3 message (step 5). Each time the connection is closed this second part (steps 3 through 6) must be repeated over the new connection (i.e. it's not enough to just keep sending the last type-3 message). Also, once the connection is authenticated, the Authorization header need not be sent anymore while the connection stays open, no matter what resource is accessed.

    For implementations wishing to work with M$'s software this means that they must make sure they use either HTTP/1.0 keep-alive's or HTTP/1.1 persistent connections, and that they must be prepared to do the second part of the handshake each time the connection was closed and is reopened. Server implementations must also make sure that HTTP/1.0 responses contain a Content-length header (as otherwise the connection must be closed after the response), and that HTTP/1.1 responses either contain a Content-length header or use the chunked transfer encoding.

    Example

    Here is an actual example of all the messages. Assume the host name is "LightCity", the NT domain name is "Ursa-Minor", the username is "Zaphod", the password is "Beeblebrox", and the server sends the nonce "SrvNonce". Then the handshake is:

        C -> S   GET ...
        
        S -> C   401 Unauthorized
                 WWW-Authenticate: NTLM
        
        C -> S   GET ...
                 Authorization: NTLM TlRMTVNTUAABAAAAA7IAAAoACgApAAAACQAJACAAAABMSUdIVENJVFlVUlNBLU1JTk9S
        
        S -> C   401 Unauthorized
                 WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABggAAU3J2Tm9uY2UAAAAAAAAAAA==
        
        C -> S   GET ...
                 Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHIAAAAYABgAigAAABQAFABAAAAADAAMAFQAAAASABIAYAAAAAAAAACiAAAAAYIAAFUAUgBTAEEALQBNAEkATgBPAFIAWgBhAHAAaABvAGQATABJAEcASABUAEMASQBUAFkArYfKbe/jRoW5xDxHeoxC1gBmfWiS5+iX4OAN4xBKG/IFPwfH3agtPEia6YnhsADT
        
        S -> C   200 Ok
    

    and the unencoded messages are:

    Type-1 Message:

           0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
       0:  4e 54 4c 4d 53 53 50 00 01 00 00 00 03 b2 00 00  "NTLMSSP........."
      10:  0a 00 0a 00 29 00 00 00 09 00 09 00 20 00 00 00  "....)....... ..."
      20:  4c 49 47 48 54 43 49 54 59 55 52 53 41 2d 4d 49  "LIGHTCITYURSA-MI"
      30:  4e 4f 52                                         "NOR"
    

    Type-2 Message:

           0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
       0:  4e 54 4c 4d 53 53 50 00 02 00 00 00 00 00 00 00  "NTLMSSP........."
      10:  28 00 00 00 01 82 00 00 53 72 76 4e 6f 6e 63 65  "(.......SrvNonce"
      20:  00 00 00 00 00 00 00 00                          "........"
    

    Type-3 Message:

           0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
       0:  4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00  "NTLMSSP........."
      10:  72 00 00 00 18 00 18 00 8a 00 00 00 14 00 14 00  "r..............."
      20:  40 00 00 00 0c 00 0c 00 54 00 00 00 12 00 12 00  "@.......T......."
      30:  60 00 00 00 00 00 00 00 a2 00 00 00 01 82 00 00  "`..............."
      40:  55 00 52 00 53 00 41 00 2d 00 4d 00 49 00 4e 00  "U.R.S.A.-.M.I.N."
      50:  4f 00 52 00 5a 00 61 00 70 00 68 00 6f 00 64 00  "O.R.Z.a.p.h.o.d."
      60:  4c 00 49 00 47 00 48 00 54 00 43 00 49 00 54 00  "L.I.G.H.T.C.I.T."
      70:  59 00 ad 87 ca 6d ef e3 46 85 b9 c4 3c 47 7a 8c  "Y....m..F...<Gz."
      80:  42 d6 00 66 7d 68 92 e7 e8 97 e0 e0 0d e3 10 4a  "B..f}h.........J"
      90:  1b f2 05 3f 07 c7 dd a8 2d 3c 48 9a e9 89 e1 b0  "...?....-<H....."
      a0:  00 d3                                            ".."
    

    For reference, the intermediate hashed passwords are:

    lm_hpw (LanManager hashed password):
    91 90 16 f6 4e c7 b0 0b a2 35 02 8c a5 0c 7a 03 00 00 00 00 00
    nt_hpw (NT hashed password):
    8c 1b 59 e3 2e 66 6d ad f1 75 74 5f ad 62 c1 33 00 00 00 00 00

    Resources

    * LM authentication in SMB/CIFS
    http://www.ubiqx.org/cifs/SMB.html#SMB.8.3
    * A document on cracking NTLMv2 authentication
    http://www.blackhat.com/presentations/win-usa-02/urity-winsec02.ppt
    * Squid's NLTM authentication project
    http://squid.sourceforge.net/ntlm/
    * Encryption description for Samba
    http://de.samba.org/samba/ftp/docs/htmldocs/ENCRYPTION.html
    * Info on the MSIE security hole
    http://oliver.efri.hr/~crv/security/bugs/NT/ie6.html
    * FAQ: NT Cryptographic Password Attacks & Defences
    http://www.ntbugtraq.com/default.asp?sid=1&pid=47&aid=17
    * M$'s hotfix to disable the sending of the LanManager response
    ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/lm-fix
    * A description of M$'s hotfix
    http://www.tryc.on.ca/archives/bugtraq/1997_3/0070.html

    Acknowledgements

    Special thanks to the following people who helped with the collection and debugging of the above information:
     


    my java 2005-08-19 13:54 鍙戣〃璇勮
    ]]>
    The NTLM Authentication Protocolhttp://www.tkk7.com/lmsun/articles/10503.htmlmy javamy javaFri, 19 Aug 2005 05:52:00 GMThttp://www.tkk7.com/lmsun/articles/10503.htmlhttp://www.tkk7.com/lmsun/comments/10503.htmlhttp://www.tkk7.com/lmsun/articles/10503.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10503.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10503.html闃呰鍏ㄦ枃

    my java 2005-08-19 13:52 鍙戣〃璇勮
    ]]>
    鍦↗ava紼嬪簭涓闂甒indows鍏變韓鏂囦歡緋葷粺 http://www.tkk7.com/lmsun/articles/10487.htmlmy javamy javaFri, 19 Aug 2005 03:18:00 GMThttp://www.tkk7.com/lmsun/articles/10487.htmlhttp://www.tkk7.com/lmsun/comments/10487.htmlhttp://www.tkk7.com/lmsun/articles/10487.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10487.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10487.html    

    鏈枃娑夊強(qiáng)鐨勫嚑涓叧閿瓧瑙i噴錛?nbsp;

    SMB: Server Message Block, 鐢ㄤ簬鍏變韓渚嬪鏂囦歡銆佹墦鍗版満銆佷覆鍙f垨鑰呮槸鍛藉悕綆¢亾絳夌敤浜庨氳鐨勬娊璞″璞★紱
    CIFS:  Common Internet File System,  SMB鐨勫寮虹増錛學(xué)indows 2000/XP瀹炵幇浜?jiǎn)璇ュ崗璁Q?BR>JCIFS: 涓涓疄鐜頒簡(jiǎn)CIFS鐨勭函Java欏圭洰錛屾棤欏諱換浣曠殑鏈湴搴撱?/P>

    JCIFS鐨勭綉鍧錛?http://jcifs.samba.org/

    涓嬮潰鎴戜滑鐪嬩竴涓潪甯哥畝鍗曠殑渚嬪瓙錛屽湪榪愯榪欎釜渚嬪瓙涔嬪墠蹇呴』鍑嗗涓ゅ彴鏈哄櫒A銆丅錛屽叾涓垜浠珹鏄垜浠▼搴忚繍琛屾墍鍦ㄧ殑鏈哄櫒錛岃孊鍒欐槸琚闂殑鏈哄櫒錛屼粎鐢˙涓婄殑Guest鐢ㄦ埛錛岃屼笖A褰撳墠鐨勭敤鎴蜂笉鑳藉瓨鍦ㄤ簬B鏈哄櫒涓紝涔熷氨鏄褰撴垜浠氳繃璧勬簮綆$悊鍣ㄨ闂?\\B 鐨勬椂鍊欙紝浼?xì)瑕佹眰杈撳叆鐢ㄦ埛鍚嶄互鍙?qiáng)鍙d護(hù)錛屽涓嬪浘鎵紺猴細(xì)

     

     

     

     

     

    榪欎釜鏃跺橝鏈哄櫒涓婄殑紼嬪簭灝變笉鑳介氳繃渚嬪 \\B\folder\1.txt 榪欐牱鐨勮礬寰勬潵璁塊棶B鏈哄櫒涓婂叡浜枃浠跺すfolder涓殑1.txt鏂囦歡錛屼篃灝辨槸璇碕ava涓嚜甯︾殑File,FileInputStream綾誨凡緇忎笉璧蜂綔鐢ㄤ簡(jiǎn)錛屼笉淇★紵 涓嶄俊浣犱斧璇曡瘯

    浣嗘槸鍊熷姪浜嶫CIFS浣犲氨鍙互寰堝鏄撶殑璁塊棶鍒版枃浠?.txt鐨勫唴瀹癸紝鎴戜滑鍏堟潵鐪嬭繖涓畝鍗曠殑渚嬪瓙錛?/P>

    import jcifs.smb.*;

    public class Demo{
        public static void main(String[] args) throws Exception{
            //灝唘ser鍜宲assword鎹㈡垚鏄疊鏈哄櫒涓婄殑鐢ㄦ埛鍚嶄互鍙?qiáng)鍙d?BR>        SmbFileInputStream in = new SmbFileInputStream("smb://user:password@B/folder/1.txt" );
            byte[] b = new byte[8192];
            int n;
            while(( n = in.read( b )) > 0 ) {
                System.out.write( b, 0, n );
            }
        }
    }

    緙栬瘧騫惰繍琛岃繖闈㈢殑渚嬪瓙渚垮彲浠ユ墦鍗版枃浠?1.txt 鐨勫唴瀹廣?BR>鎶婁笂闈緥瀛愪腑鐨勫瘑鐮佸~鍐欐垚涓涓敊璇殑瀵嗙爜鍐嶈繍琛岀▼搴忥紝渚夸細(xì)寰楀埌 jcifs.smb.SmbAuthException 寮傚父銆?BR>
    鍐欐枃浠朵篃鏄竴涓亾鐞嗭紝鍏充簬鏂囦歡鐨勬搷浣淛CIFS鎻愪緵浜?jiǎn)杩欎箞鍑犱釜绫诲Q歋mbFile,SmbFileInputStream,SmbFileOutputStream錛屽叿浣撶殑鐢ㄦ埛璺烰ava涓搴旂殑綾誨樊涓嶅銆?/P>

    JCIFS涓枃浠剁殑URL涔熷氨鏄痵mb_url錛屾牸寮忎負(fù)錛歴mb://{user}:{password}@{host}/{path} 錛屽彧瑕佸~濂借繖涓猆RL錛孞CIFS灝變細(xì)甯綘鎼炲畾韜喚楠岃瘉鐨勪簨錛岀矇綆鍗曠殑銆?/P>

    my java 2005-08-19 11:18 鍙戣〃璇勮
    ]]>
    鐢↗AVA璁塊棶鍏變韓鏂囦歡緋葷粺http://www.tkk7.com/lmsun/articles/10485.htmlmy javamy javaFri, 19 Aug 2005 03:16:00 GMThttp://www.tkk7.com/lmsun/articles/10485.htmlhttp://www.tkk7.com/lmsun/comments/10485.htmlhttp://www.tkk7.com/lmsun/articles/10485.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10485.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10485.html

    [ 2004-8-10 21:49:00 | By: roof ]

    鍓嶈█

    鍦∕icrosoft 緗?緇?緋?緇?涓紝SMB錛圫erver Message Block錛?鏈?鍔?淇?鎭?鍧楋級(jí) 鍗?璁?鏄疻indows for Workgroup(WfWg)銆乄indows 95銆乄indows NT 鍜孡anManager 鐢?鏉?瀹?鐜?鍏?浜?灞 鍩?緗?涓?鏂?浠?鍜?鎵?鍗?鏈?鐨?鍗?璁?瀵?浜?鍒?鐢↙inux 鍜學(xué)indows NT 鏋?寤?鐨?灞 鍩?緗?鏉?璇達(dá)紝Samba 灝?鏄?涓篖inux 鎻?渚?鐨凷MB 瀹?鎴?紼?搴? 鏈?鍔?鍣?紼?搴?鐨?杞?浠?鍖咃紝 鍏?鍔?鑳?鏄?瀹?鐜癢indows 鍜孡inux 浜?鐩?鍏?浜?瀵?鏂?鐨?紓?鐩?絀?闂?鍜?鎵?鍗?鏈恒傞氱敤緗戠粶鏂囦歡緋葷粺綆縐癈IFS,瀹冧簨瀹炰笂鏄痺indows騫沖彴鏂囦歡鍏變韓鐨勬爣鍑嗗崗璁紝瀹冩槸windows explorer,緗戠粶閭誨眳鍜屾槧灝勭綉緇滈┍鍔ㄥ櫒鐨勫簳灞傚疄鐜板崗璁侸AVA鍏鋒湁澶╃劧鐨勫鉤鍙版棤鍏蟲(chóng)э紝浣跨敤JAVA鍙互璁塊棶浠諱綍綾誨瀷鐨勬湇鍔″櫒鎴栧鎴鋒満涓婄殑鍏變韓鏂囦歡緋葷粺錛屽茍涓旂紪鍐欑殑杞歡浜у搧鍙互榪愯浜庝換浣曞鉤鍙幫紝鍥犳鐢↗AVA璁塊棶鍏變韓鏂囦歡緋葷粺鍦ㄤ紒涓氬簲鐢ㄤ腑鍏鋒湁寰楀ぉ鐙帤鐨勪紭鍔褲?/P>

    JAVA涓殑CIFS瀹炵幇

    Jcifs鏄疌IFS鍦↗AVA涓殑涓涓疄鐜幫紝鏄痵amba緇勭粐鏈潃linux鐨勭簿紲烇紝璐熻矗緇存姢寮鍙戠殑涓涓紑婧愰」鐩傝繖涓」鐩笓娉ㄤ簬浣跨敤java璇█瀵筩ifs鍗忚鐨勮璁″拰瀹炵幇銆備粬浠皢jcifs璁捐鎴愪負(fù)涓涓畬鏁寸殑錛屼赴瀵岀殑錛屽叿鏈夊彲鎵╁睍鑳藉姏涓旂嚎紼嬪畨鍏ㄧ殑瀹㈡埛绔簱銆傝繖涓搴撳彲浠ュ簲鐢ㄤ簬鍚勭java铏氭嫙鏈鴻闂伒寰狢IFS/SMB緗戠粶浼犺緭鍗忚鐨勭綉緇滆祫婧愩傜被浼間簬java.io.File鐨勬帴鍙e艦寮忥紝鍦ㄥ綰跨▼鐨勫伐浣滄柟寮忎笅琚瘉鏄庢槸鏈夋晥鑰屽鏄撲嬌鐢ㄧ殑銆傜洰鍓峧cifs鐨勬渶鏂扮増鏈槸jcifs-0.8.0b錛屼綘鍙互鍦ㄦ湰鏂囨渶鍚庡垪鍑虹殑鍙傝冭祫鏂欎腑鑾峰緱涓嬭澆榪欎竴綾誨簱鐨勭綉鍧錛岃繖涓鐗堟湰榪樻敮鎸佸垎甯冨紡鐨勬枃浠剁郴緇燂紝鏈枃灝氫笉娑夊強(qiáng)榪欎竴鍐呭銆?/P>

    JAVA/CIFS紼嬪簭璁捐

    濡傛灉浣犳浘緇忎嬌鐢ㄨ繃java鐨勬枃浠舵搷浣滃姛鑳斤紝閭d箞浣犲皢寰堝鏄撴帉鎻cifs鐨勫紑鍙戞柟娉曘侸cifs閫氳繃綾諱技濡備笅鐨勮祫婧恥rl瀹氫綅涓涓祫婧愶細(xì)

    smb://guest:1234@192.168.3.56/share/a.txt

    榪欎釜url鐨勫紑濮嬮儴鍒唖mb:// 璇存槑浜?jiǎn)杩欐槸涓涓猻mb綾誨瀷鐨剈rl錛涙帴涓嬫潵鐨刧uest鍜?234鍒嗗埆鏄闂叡浜祫婧愮殑鐢ㄦ埛鍚嶇О鍜屽瘑鐮侊紱@鍚庨潰鏄璁塊棶鐨勮祫婧愮殑涓繪満鍚嶆垨IP鍦板潃銆傛渶鍚庢槸璧勬簮鐨勫叡浜枃浠跺す鍚嶇О鍜屽叡浜祫婧愬悕銆?

    鍦↗AVA紼嬪簭涓紝浣跨敤濡備笅鏂瑰紡鑾峰緱涓涓繙紼嬪叡浜枃浠剁殑鍙ユ焺錛?

    SmbFile file = new SmbFile("smb://guest:1234@192.168.3.56/share/a.txt");

    榪欓噷鐨勫彞鏌勪笉浠呴檺浜庤繙紼嬬殑鍏變韓鏂囦歡錛岃繕鍙兘鏄叡浜枃浠跺す銆俰sFile()鏂規(guī)硶鍜宨sDirectory()鐢ㄦ潵鍒ゆ柇榪欎釜鍙ユ焺瀵瑰簲鐨勮祫婧愮殑鐪熷疄灞炴с傚鏋滄槸鍏變韓鏂囦歡澶癸紝閫氳繃璋冪敤瀹冪殑list()鏂規(guī)硶灝嗚幏寰楀叾涓祫婧愮殑鍒楄〃銆侺ist鏂規(guī)硶鏀寔榪囨護(hù)鍣ㄦ満鍒訛紝鏈変袱縐嶈繃婊ゅ櫒鍙緵浣跨敤錛屼竴縐嶆槸SmbFileFilter,鍙︿竴縐嶆槸SmbFilenameFilter錛岃繖涓や釜鍦╦cifs涓綔涓烘帴鍙e嚭鐜幫紝浣犲彲浠ユ牴鎹嚜宸辯殑闇瑕佹淳鐢熷嚭涓у寲鐨勮繃婊ゅ櫒錛屽疄鐜版帴鍙d腑鐨刟ccept鏂規(guī)硶錛屼互婊¤凍涓嶅悓涓氬姟鐨勯渶姹傘?

    SmbFileInputStream鏄痵mb鏂囦歡鐨勮緭鍏ユ祦錛屽畠鐨勫姛鑳芥槸浠ユ祦鐨勬柟寮忔墦寮涓涓猄mbFile錛?

    SmbFileInputStream in = new SmbFileInputStream(file);

    SmbFileInputStream鎻愪緵read鏂規(guī)硶錛屼綘鍙互浠庤繖涓祦涓鍑?guó)櫩溄E嬫枃浠跺叏閮ㄧ殑鍐呭銆?

    鑷蟲(chóng)錛屼綘宸茬粡鎺屾彙浜?jiǎn)java璁塊棶smb鏂囦歡緋葷粺鐨勫熀鏈柟娉曘?

    SmbFileOutputStream鏄痵mb鏂囦歡鐨勮緭鍏ユ祦錛屽彲浠ュ悜榪滅▼鏂囦歡緋葷粺閫氳繃smb鍐欏叆鏁版嵁錛屾柟娉曚笌涓婇潰綾諱技錛屼笉鍐嶈禈榪般?

    鏈枃鍚庨潰闄勫甫鐨勬簮浠g爜鏄竴涓畬鏁寸殑渚嬪瓙錛屽畠瀹屾垚鍔熻兘寰堢畝鍗曪紝灝辨槸灝嗗彟涓鍙扮數(shù)鑴戜笂鎸囧畾鍏變韓鏂囦歡澶逛笅鐨勬煇浜涙枃浠舵嫹璐濆埌鏈満鐨勬寚瀹氱洰褰曚笅銆傞氳繃榪欎釜渚嬪瓙錛岀浉淇′綘寰堝鏄撳皢瀹冪Щ妞嶅埌浣犵殑寮鍙戜駭鍝佷腑銆?/P>

    絎竴姝ワ紝璁劇疆榪愯鐜銆傚皢婧愪唬鐮佽В鍘嬬緝錛屽皢lib鐩綍涓嬬殑鍚嶇О涓簀cifs-0.8.0b.jar鐨勬枃浠跺姞鍏ュ埌浣犵殑鎿嶄綔緋葷粺鐨刢lasspath涓紝浣跨ず渚嬬▼搴忚繍琛屾椂鑳藉鎵懼埌榪欎釜搴撱?/P>

    絎簩姝ワ紝鍦ㄥ彟涓鍙拌綆楁満涓婂緩绔嬪悕縐頒負(fù)share鐨勫叡浜枃浠跺す,鐢ㄦ埛鍚嶄負(fù)guest,瀵嗙爜涔熶負(fù)guest銆傚亣璁捐繖鍙拌綆楁満鐨刬p鍦板潃鏄?92.168.0.2銆?/P>

    絎笁姝ワ紝鍦ㄥ垰鎵嶅緩绔嬬殑鍏變韓鏂囦歡澶逛笅鏀劇疆涓や釜鏂囦歡錛屽悕縐板垎鍒負(fù)hello.txt錛宐ye.txt銆傛枃浠剁殑鍐呭鏃犳墍璋撱?/P>

    絎笁姝ワ紝鍦ㄦ湰鍦拌綆楁満涓婄殑C鐩樿窡鐩綍涓嬪緩绔嬩竴涓悕縐頒負(fù)tmp鐨勭┖鐩綍錛岀疆姝ょ洰褰曞彲鍐欍?/P>

    絎洓姝ワ紝緙栬瘧榪愯Sample1.java錛屽茍榪愯錛?/P>

    Java Sample1 192.168.3.52 guest guest /share/ c:/tmp/

    媯(gè)鏌:\tmp鏂囦歡澶?浼?xì)鍙戠幇hello.txt榪欎釜鏂囦歡琚鍒跺埌浜?jiǎn)鏈満锛岃宐ye.txt娌℃湁琚鍒訛紝鍥犱負(fù)Sample1.java涓嬌鐢ㄤ簡(jiǎn)榪囨護(hù)鍣紝浠呭厑璁稿悕縐頒負(fù)hello寮澶寸殑鏂囦歡琚嫹璐濄?/P>

    鍚庤

    瀵瑰叡浜枃浠剁郴緇熺殑璁塊棶鏄唴閮ㄥ姙鍏郴緇熺瓑娑夊強(qiáng)鍒版枃浠惰縼縐葷殑杞歡浜у搧寮鍙戣繃紼嬩腑涓嶅彲鍥為伩鐨勮棰橈紝jCifs鏄竴濂楅拡瀵硅繖涓璇鵑瀹屾暣鑰屽己澶х殑瑙e喅鏂規(guī)錛岄氳繃瀹冧綘鍙互瀹炵幇瀵逛換浣曞叡浜枃浠剁郴緇熺殑璁塊棶銆?/P>

    涓浜涙湁鐢ㄧ殑璧勬簮鍜屽弬鑰冭祫鏂?/B>

    鏈枃鐨勫叏閮ㄦ簮浠g爜錛屽彲緙栬瘧榪愯錛屼緵璇昏呯爺絀訛紝涓嬭澆婧愪唬鐮?/A>銆?/P>

    濡傛浜?jiǎn)瑙f洿澶氬叧浜巎cifs鐨勪俊鎭紝璇瘋闂叾瀹樻柟緗戠珯 http://jcifs.samba.org/銆?/P>

    鎮(zhèn)ㄥ彲浠ュ湪 http://users.erols.com/mballen/jcifs/ 鑾峰緱jcifs搴撶殑鏈鏂扮増鏈?/P>

    濡傛灉浣犲smb榪樹(shù)笉鏄崄鍒嗙啛鎮(zhèn)夛紝榪欓噷鏈変竴綃囦笉閿欑殑鏂囩珷灝嗗悜浣犱粙緇嶄粈涔堟槸smb錛?A >http://samba.anu.edu.au/cifs/docs/what-is-smb.html銆?/P>



    my java 2005-08-19 11:16 鍙戣〃璇勮
    ]]>
    Easy Windows Authentication with Tomcat 4.xhttp://www.tkk7.com/lmsun/articles/10398.htmlmy javamy javaThu, 18 Aug 2005 03:07:00 GMThttp://www.tkk7.com/lmsun/articles/10398.htmlhttp://www.tkk7.com/lmsun/comments/10398.htmlhttp://www.tkk7.com/lmsun/articles/10398.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10398.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10398.htmlEasy Windows Authentication with Tomcat 4.x Category: Java

    The original blog entry by Robert Rasmussen has disappeared from the Internet (cannot find server) so I'm reproducing it here via Google's caching feature. I've made a few changes to pretty up the formatting, but that's about it.

    I've been pulled into a little internal project, and one of the requirements is that users should be able to authenticate with their Windows login and password. IIS may or may not be in the picture.

    Since the server is a Windows 2000 machine, this turns out to be extremely simple to do thanks to Andy Armstrong's JAAS login modules.

    Once you've downloaded the login modules, set your classpath accordingly and make sure that the directory holding NTSystem.dll is in your %PATH% variable. Next, in the "Sample config" folder you'll find a tagish.login file and a java.security.sample file. The last line in the .sample file is significant, and it needs to be in your $JAVA_HOME/jre/lib/security folder (in a file named java.security). You should copy the tagish.login file there as well. If your users will always be logging into the same domain (which is the case in my situation), just set the defaultDomain property in tagish.login, like this:

    NTLogin
    {
        com.tagish.auth.win32.NTSystemLogin required returnNames=true returnSIDs=false defaultDomain=YOUR_DOMAIN_HERE;
    };
    

    Now, all you need to do to use Windows authentication in your webapps is to make one addition to your server.xml file (or to your specific context's definition):

    <Realm className="org.apache.catalina.realm.JAASRealm" debug="99"
           appName="NTLogin"
           userClassNames="com.tagish.auth.win32.NTPrincipal"
           roleClassNames="com.tagish.auth.win32.NTPrincipal" />
    

    I'll admit this config is slightly hokey. If you look at the Catalina JAASCallbackHandler (which is hardwired to JAASRealm), the way that I have the realm configured above pretty much counts on the User principal (in effect, the user name) being the first principal returned. This is evil, but it works. It would be nice if either Catalina allowed a pluggable CallbackHandler so that I could take advantage of the NTPrincipal.getType() method or if Andy's code returned subclasses of NTPrincipal like UserPrincipal or GroupPrincipal that I could specify in server.xml.

    Once you've got this all configured, the various groups your users belong to equate to role names (so if I belong to an administrators group, my authenticated user will be in role "administrators"), and you can configure security in your webapps using these roles.


    浜屾湀 17, 2003 04:11 涓嬪崍 MST Permalink

    鍙嶅悜璺熻釜 URL: http://raibledesigns.com/trackback/rd/sunsets/easy_windows_authentication_with_tomcat
    鐣欒█:

    Thanks for posting this, Matt.

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Robert Rasmussen on 2003騫?2鏈?7鏃? 09:18 涓嬪崍 MST #

    I have tired this module and used the form authenication in the tomcat. Howerver, it seems cannot login in successfully as it always go into the pages. Please help!!

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Jimmy Wong on 2003騫?2鏈?8鏃? 12:42 涓婂崍 MST #

    Make sure the path to NTSystem.dll is in your PATH environment variable and that tagishauth.jar is in your $CATALINA_HOME/common/lib. Currently, I believe this only works on a Windows machine. HTH, Matt

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Matt on 2003騫?2鏈?8鏃? 07:00 涓婂崍 MST #

    If I am running a JVM under an already authenticated NT user, does anyone know how I can easily get the NT domain that the user authenticated to ? Thanks !

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Nicholas Whitehead on 2003騫?2鏈?0鏃? 11:59 涓婂崍 MST #

    How can I get Subject in my web application with JAASRealm?

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Roman Velichko on 2003騫?8鏈?6鏃? 12:21 涓婂崍 MDT #

    The same way you always have - request.getRemoteUser()

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Matt Raible on 2003騫?8鏈?6鏃? 08:10 涓婂崍 MDT #

    This tutorial is out of date...Andy Armstrong updated tagish a few months back...it now has more useful types like NTUserPrincipal and NTGroupPrincipal and a few bug fixes. Also, depending on your requirements, the NTLM functionality added in JDK1.4.2 might help.

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Robert Rasmussen on 2003騫?8鏈?6鏃? 10:58 涓婂崍 MDT #

    request.getRemoteUser() does return a String not JAAS's Subject.

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Tomasz Luczynski on 2004騫?3鏈?9鏃? 03:23 涓婂崍 MST #

    [Trackback] This is the solution for my previous post. Samba NTLM Authentication: (Get it here.) This package configures exactly as described. I used the example servlet (NtlmHttpAuthExample) included with the package and set up the filter as in the docs. ...

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Chris Maeda on 2004騫?7鏈?8鏃? 10:24 涓婂崍 MDT
    绔欑偣錛?http://www.cmaeda.com/index.php?p=22 #

    My blog has current info for setting up Tagish 1.03 with Tomcat5.

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Chris Maeda on 2004騫?7鏈?8鏃? 10:38 涓婂崍 MDT
    绔欑偣錛?http://cmaeda.com/index.php?p=22 #

    鐢?B minmax_bound="true">{0}鍙戣〃浜?69.193.88.30 on 2004騫?1鏈?9鏃? 03:12 涓婂崍 MST
    绔欑偣錛?http://www.jenniferconnor.com/ #

    鐢?B minmax_bound="true">{0}鍙戣〃浜?69.193.88.30 on 2004騫?1鏈?4鏃? 01:53 涓婂崍 MST
    绔欑偣錛?http://www.36busty.com/00005602.shtml #

    鐢?B minmax_bound="true">{0}鍙戣〃浜?69.42.81.244 on 2005騫?1鏈?1鏃? 02:32 涓婂崍 MST
    绔欑偣錛?http://www.johnhuron.com/ #

    Hi Matt, Are you still using tagish library with Tomcat 5.x versions?? If yes, could you please point out the final installing directions. With the present blog instructions from Chris Maeda, they doesn't work at all. You can see the problems at http://www.cmaeda.com/index.php?p=22 Please advice. thanks aks

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Vicky on 2005騫?4鏈?1鏃? 10:45 涓婂崍 MST #

    I prefer not to put my config in $JAVA_HOME/jre/lib/security/java.security instead, use this property when you start tomcat: -Djava.security.auth.login.config=c:/path/to/your/tagish.login

    鐢?B minmax_bound="true">{0}鍙戣〃浜?Joe Scalise on 2005騫?8鏈?8鏃? 02:41 涓嬪崍 MDT
    绔欑偣錛?http://www.einvite.com #



    my java 2005-08-18 11:07 鍙戣〃璇勮
    ]]>
    Java Authentication and Authorization http://www.tkk7.com/lmsun/articles/10366.htmlmy javamy javaWed, 17 Aug 2005 09:38:00 GMThttp://www.tkk7.com/lmsun/articles/10366.htmlhttp://www.tkk7.com/lmsun/comments/10366.htmlhttp://www.tkk7.com/lmsun/articles/10366.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10366.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10366.htmlIntroduction
    This paper explains how to use the Java Authentication and Authorization API (JAAS). It plugs JAAS into the Struts framework. Though this paper focuses on Struts, and in particular the example application distributed with Struts, the lessons learned should be applicable to any MVC web framework.

    In addition, while there are many articles on authentication with JAAS [1], [2] , using the API for authorization is relatively undocumented [3]. This paper will show how to use JAAS to secure resources in an MVC architecture.

    There are two points of integration with Struts. During the login process and when the client requests a resource from Struts (which will usually be a URL). At each of these points, the application should defer to JAAS classes to perform the action.

    This paper will first examine the JAAS infrastructure and then explain how the integration outlined above took place.

     

    Who should read this
    This article is for developers who are relatively familiar with web applications and the java security framework. A sample application in Struts is used for the examples [4], but familiarity with Struts is not required. For information on java security, check out Java Security by Scott Oaks. For information on web applications, check out Sun's web site [5]. For information on Struts, check out the Struts web site [6].

     

    Conventions
    For the purposes of printing, text that should be on one line will be broken up into more. This will be indicated by a backslash (\) at the end of the line.

     

    Authentication
    Login Module
    The login module receives information about the user and authenticates the user, thereby verifying that he or she is a valid subject. There are several implementations of login modules currently available. If a custom login module is needed, resources are available [8].

    Login Module implementations

    Sun provides default implementations for Solaris and NT.


    Tagish has several implementations licensed under the GPL [9].


    JBoss provides several implementations [10].
    Note: For WebLogic 6.1 and Tomcat 3.2, both the jaas.jar and the login module classes needed to be in the non webapp specific classpath.

    These login modules are identified by a name in a configuration file and then called by a LoginContext class that JAAS provides. The LoginContext class does not appear to be thread safe--the javadoc states that " a LoginContext should not be used to authenticate more than one Subject. A separate LoginContext should be used to authenticate each different Subject" [11]. Most of these modules expect to be run from an application or on the command line, and thus to be able to interact directly with a user. Since a web application resides on a server, it may be necessary to write an adapter to pull the needed user information from where the web application stores it and place it in a form that the login module can process.

     

    Module Configuration
    In addition to putting classes that can do authentication in the correct classpath location, some configuration is required to let the JAAS classes know what type of authentication is possible. JAAS allows complex login schemes [12], however, for most web applications, such complexity is not required. Typically, a username and password will be read from a form, and compared against known server side values. An authentication scheme which verifies a username and password combination against a server side file will be examined below.

    Example 1. JAAS login module configuration file

    FileLogin
    {
                com.tagish.auth.FileLogin required debug=true \
                pwdFile="/usr/local/tomcat/webapps/struts-example/WEB-INF/passwd";
    };

    In Example 1, the FileLogin authentication scheme has one required module. FileLogin implemented by the com.tagish.auth.FileLogin class. Both the class name and a token indicating the relationship of the module to the scheme are mandatory. Here the required token indicates that the FileLogin module must validate this login or the scheme as a whole fails. It is also possible to pass additional information to the login module in this configuration file. This module needs to know where its password file is located.

    Since this configuration file may be located anywhere on the file system, the authentication classes need to be informed where this file is. There are two ways to do this: adding parameters to a JVM wide general configuration file (java.security), or passing the information in on the command line when starting the JVM.

     

    Setting Login Configuration Information Via java.security
    This file is where the JVM looks for security related configuration parameters. It is typically located in the JAVA_HOME/jre/lib/security directory. It is possible to have an arbitrary number of login configuration files detailing any number of authentication schemes. These are "read and unioned into one single configuration" [13].

    Example 2. java.security entry for login module configuration

    login.config.url.1=file:${java.home}/lib/security/tagish.login
    login.config.url.2=file:${java.home}/lib/security/struts.login

    This entry specifies the location of files containing authentication scheme definitions. Also, note that java system properties may be referenced in java.security.

    If the second line looked like login.config.url.3=file:${java.home}/lib/security/struts.login (note the 3), then struts.login would not be searched for login modules. Scanning begins at login.config.url.1 and continues to increment the suffix until no file is found. This is an implementation detail of the default Sun provided authentication classes. For more information, read about the Login Configuration Provider [14].

     

    Setting Login Configuration Via the Command Line
    It is also possible to set a java property on the command line when starting the JVM that tells it where to look for the JAAS login scheme configuration file. The property name is java.security.auth.login.config.

    Example 3. Setting the location of the login scheme configuration file on the command line

    $ java ... \
    -Djava.security.auth.login.config==$JAVA_HOME/jre/lib/security/tagish.login ...

    This command line overrides any previously set value for the login scheme configuration file location. In typical java fashion, if there was just one = in Example 3, an additional location for the login scheme configuration file would be specified.

     

    Integrating Authentication Into Struts
    After the login module is recognized by JAAS, hooks into the web application need to be written. In the example application, an Action class takes a username and password from its Form class and authenticates the user against a database. This is the logical place to hook in the JAAS authentication module.

    The Struts example application has a LogonAction class. Initially, the relevant portion of this class looks like this (note that this code is unchanged except to break up lines for ease of printing).

    Example 4. Initial LogonAction Authentication

       125          String username = ((LogonForm) form).getUsername();
       126          String password = ((LogonForm) form).getPassword();
       127          Hashtable database = (Hashtable)
       128            servlet.getServletContext().getAttribute( \
                            Constants.DATABASE_KEY \
                            );
       129          if (database == null)
       130              errors.add(ActionErrors.GLOBAL_ERROR,
       131                         new ActionError("error.database.missing"));
       132          else {
       133              user = (User) database.get(username);
       134              if ((user != null) && !user.getPassword().equals(password))
       135                  user = null;
       136              if (user == null)
       137                  errors.add(ActionErrors.GLOBAL_ERROR,
       138                             new ActionError("error.password.mismatch"));
       139          }


    On line 125 and 126, the username and password that were submitted on the form are extracted into local variables. The code looks for an authentication database and verifies its existence on lines 127-132. Line 134 is where the actual authentication occurs. If the user exists in the database and the password in the database is the same as the password entered on the form, then the user is authenticated.

    This approach works just fine for a sample application. The LogonAction class does all of the authentication in the perform method. But the LogonAction class should be a thin layer deferring the actual work to business objects. In addition, switching the source users are authenticated against requires changes to this class since it is hard coded to expect a password and username. Also, as mentioned in the "Login Module" section, using the JAAS authentication module will be difficult, as most implementations expect some level of user interaction. Putting a business object between the Struts application classes and the JAAS classes can make life easier.

    Example 5. Modified LogonAction Authentication

      125          String username = ((LogonForm) form).getUsername();
       126          String password = ((LogonForm) form).getPassword();
       127          Hashtable database = (Hashtable)
       128            servlet.getServletContext().getAttribute(Constants.DATABASE_KEY)
       129          if (database == null)
       130              errors.add(ActionErrors.GLOBAL_ERROR,
       131                         new ActionError("error.database.missing"));
       132          else {
       133              Auth fa = new com.xor.auth.FileAuth(username,password);
       134              if (fa.authenticate()) {
       135                  user = (User) database.get(username);
       136                  HttpSession sess = request.getSession();
       137                  sess.setAttribute(Auth.SUBJECT_SESSION_KEY, fa.getSubject());
       138              }

    Lines 125-132 are the same in this example as they were in Example 4. However, rather than the LogonAction class performing the authentication, it defers to a special Auth class. Note that on line 135, the database is still used to get the User object, since the sample application used it in other code.

    Auth is a custom interface specifying the contract that the adapter for the JAAS classes must fulfill to interface with web applications in general and this example application in particular. FileAuth is an implementation of that interface which adapts the com.tagish.auth.FileLogin login module specified in Example 1.

     

    Calling the Tagish Authentication Module
    The FileAuth class defers to the FileLogin class for almost all its functionality.

    Example 6. The authenticate Method of the FileAuth Class

         1     public boolean authenticate() {
         2         try {
         3             lc = new LoginContext("FileLogin", \
                            new MyCallBackHandler(username,password));
         4             lc.login();
         5         } catch (LoginException le) {
         6             return false;
         7         }
         8         return true;
         9     }

    On line 3, the LoginContext object is told to look for the FileLogin authentication scheme, and passed a custom callback handler. Normally, callback handlers interact with the user and retrieve information needed for authentication, but the ActionForm class has already done this. In a way, the form is a "call forward" handler, because the request/response paradigm of the web does not fit well with the client/server architecture of which the callback handler is part. The problem is worked around by passing the needed information to the callback handler on instantiation.

    On line 4, the LoginContext attempts to login the user via the modules found in the FileLogin authentication scheme. If the login fails for any reason, a LoginException will be thrown, otherwise flow continues normally. A Subject is instantiated by the login module and exposed as a property of the LoginContext object. The Subject is also populated with the Principals associated with that user by the login module.

     

    Cache Subject in Session
    After successfully authenticating the user, the Subject should be stored in the HttpSession. (The Subject is small; one Subject with one Principal serialized to a file 337 bytes in size.) This caching allows other parts of the application to perform authorization checks without requiring the user to login again. It also ensures that the other parts of the application are aware that the user has been authenticated, and logs out the user when the HttpSession expires. The storage process is shown on line 137 of Example 5; here the portion of the API of the login module that returns the newly authenticated Subject is examined. To retrieve the subject, the FileAuth class again defers to the LoginContext.

    Example 7. The FileAuth Class Exposes the Subject

         1     public Subject getSubject() {
         2         if (lc == null) {
         3             throw new IllegalStateException("either login failed or \
                    the authenticate method hasn't been called.");
         5         } else {
         6             return lc.getSubject();
         7         }
         8     }

    The getSubject method can only be called after the authenticate method.

    Of course, another option would be to store the username and password in the session, and re-authenticate every time. If the Subject were large and the authentication process was fairly fast, this option might be viable.

     

    Authorization
    Permissions
    Permissions are the heart of authorization; they control access to resources. However, the JAAS permissions are built on top of the existing java security model. This model is very good for controlling access to resources like sockets and files, but has no concept of URLs. Thus, to apply JAAS to a web application, a new permission class must be created.

     

    Create permission class
    A custom Permission class that understands URLs must be created. There are two ways to do this.

    Extending java.security.BasicPermission is one option. Using this would tie permissions to literal URLs (e.g, one could say that the admin principal should have access to the /admin/index.do page). However, the other option would be better: to create a URLPermission class extended the java.security.Permission class and handled wild cards in a manner similar to the java.io.FilePermission class [15]. Then, one could say that the admin principal should have access to the /admin/ directory and all resources below it.

    In either case, since URLs are read only, there is no need for any of these permissions to have an action attribute. On the other hand, it may be useful to specify an attribute of a Permission to determine whether a given URL may only be viewed over a secure connection. For more on extending Permissions in novel manners, see the interesting IBM article titled Extend JAAS for class instance-level authorization [16].

    However, since this is a proof of concept, a BasicPermission implementation is fine. For a production system, subclassing Permission would be required.

     

    Access Control Policy Configuration Files
    The default configuration for JAAS permissions looks much like the configuration for normal java security. Java security entries consist of a listing of permissions. The permissions can be limited to either a specific code base, or code that has been signed by a specific person, or both. JAAS permission listings can have none, one or both of these elements. However, at least one Principal association is required.

    Example 8. Sample JAAS policy file


    grant  Principal * * {
      permission com.xor.auth.perm.URLPermission \
      "/struts-example/logoff.do";
    };

    grant  Principal com.tagish.auth.TypedPrincipal "user" {
      permission com.xor.auth.perm.URLPermission \
      "/struts-example/editRegistration.do";
    };

    grant  Principal com.tagish.auth.TypedPrincipal "admin" {
      permission com.xor.auth.perm.URLPermission \
      "/struts-example/editRegistration.do";
      permission com.xor.auth.perm.URLPermission \
      "/struts-example/adminMenu.do";
    };


    The first grant allows everyone to view the logoff.do resource. Anyone with the user Principal is allowed to view /struts-example/editRegistration.do.

    At times there will be principals that are granted a superset of the permissions granted to other principals. For example, in Example 8, subjects with the admin principal can view all resources that subject with the user principal can. However, the /struts-example/editRegistration.do URL is listed twice (once in the user section and once in the admin section). It would be nice to be able to avoid duplicating permissions and delineating this relationship between principals, but this is not possible. While more than one principal can be listed for a given set of permissions, if that happens, "[t]he current Subject running the code must have all of the specified Principals in its Principal set to be granted the entry's Permissions" [17]. However, this problem may be dealt with by granting all users with the admin Principal the user Principal as well.

    On the other hand, it is possible to have permissions be supersets of other permissions. The implies method of the Permission class can be overridden to provide this behavior. For example, there could be an admin Permission which could imply all other URL permissions.

    Note: Example 8 is an example of a file based implementation of the policy. It canbe replaced with a RDBMS implementation by changing the value of the auth.policy.provider variable in the java.security file.
    Since the policy file may be located anywhere, JAAS needs to be told where to look for it (this problem is similar to that faced by the authentication configuration setup detailed in Section 2.2. There are two ways to do this: adding parameters to a system wide general configuration file (java.security), or passing the information in as a command line option when starting the JVM.


    Note: With WebLogic 6.1, only the command line method worked. Tomcat 3.2 seemed to work with both methods.


    Setting the JAAS Policy File Location in the java.security file
    This file is where the JVM looks for security related configuration parameters. It is typically located in the JAVA_HOME/jre/lib/security directory. It is possible to have arbitrary numbers of JAAS policy files. These are "read and unioned into one single policy" [18].

    Example 9. java.security entry for permission policy configuration

    auth.policy.url.1=file:${java.home}/lib/security/struts.policy
    auth.policy.url.2=file:${user.home}/.struts.policy

    This example should check the policy files in both places. Note also that java system properties can be referenced in the java.security file.

    If the second line looked like auth.policy.url.3=file:${user.home}/.struts.policy (note the 3), then the .struts.policy file would not be searched for permission sets. Scanning starts at auth.policy.url.1 and increments the suffix by one until there is no file found. This is an implementation detail of the default Sun permission file parsing class. Obviously, an authorization scheme that used a database would have different behavior.

     

    Setting the JAAS Policy File Location Via the Command Line
    It is also possible to set a java property on the command line when starting the JVM that tells it where to look for the JAAS policy file. The property name is java.security.auth.policy.

    Example 10. Setting the location of the JAAS policy file on the command line

    $ java ... \
    -Djava.security.auth.policy==$JAVA_HOME/jre/lib/security/struts.policy ...

    This command line overrides any previously set location of the JAAS policy file. If there was only one =, the property would indicate an additional policy file path.

     

    Integrating Authorization into Struts
    Now that permissions have been set up and JAAS knows about them, it is time to actually apply them in the context of the application. Every java class that accesses a potentially security sensitive resource needs to check to see if the SecurityManager is running, and if so verify that the calling class is running in a context that allows the access.

    Example 11. Typical permission check

    Permission p = new FilePermission("/tmp/foo","read");
    SecurityManager s = System.getSecurityManager();
    if ( s != null) s.checkPermission(p);

    The code here is trying to read /tmp/foo. If no SecurityManager is installed (typically via the -Djava.security.manager command line switch), System.getSecurityManager() returns null, and access does not need to be verified.

    The web application needs to perform a similar check for each URL that the user is trying to view. In an MVC architecture, the logical place to put such access control is the controller. In Struts, the ActionServlet is the controller. For the sample application the controller class, org.apache.struts.action.ActionServlet, was subclassed, and the process method was overridden.

     

    Installing Access Control Logic into the ActionServlet
    First of all, it is important to note that when the ActionServlet is subclassed to provide authorization services, only resources that the ActionServlet controls are protected. Thus, in the example application, only Actions are protected. In a real application, it'd be better to have two methods of access control:

    A central servlet which checks authorization before any URL is viewed. For example, all users may need to be logged in before viewing any pages. (If using the 1.3 version of the servlet specification, a filter might be a good choice.)


    A JSP tag or other method which may be used to check to see if a user has a given principal before showing content fragments. For example, a menu item may only be accessible to users with the admin permission.
    Both of these should delegate to a business class that does the actual security check.

    There are at least two pages whose view should not be protected at all: the login page and the login error page. In addition, there are certain security attributes that are peculiar to web applications; for example, some users may need to have all interaction over an SSL connection. The controller needs to do at least three things to provide authorization services for a web application.

    Recognize which pages are viewable by every authenticated user and respond accordingly.


    Recognize which state, secure or non secure, a request is in and respond accordingly.


    Check to see that a user is allowed to view a given URL and respond accordingly.


    The ActionServlet Subclass
    Example 12. The Overridden process Method


         1    protected void process(HttpServletRequest request, \
                HttpServletResponse response)
         2    throws ServletException, java.io.IOException
         3    {
         4        String loginPage = request.getContextPath()+"/logon.do";
         5        String pageReq = request.getRequestURI();
         6        Permission perm = \
                    PermissionFactory.getInstance().getPermission(pageReq);
         7        Subject subject = \
                    ((Subject)(request.getSession().getAttribute( \
                        Auth.SUBJECT_SESSION_KEY)));
         8        if (subject == null && \
                    (! request.getRequestURI().equals(loginPage))) {
         9            // redirect to login page
        10        } else if (subject == null &&  \
                    request.getRequestURI().equals(loginPage)) {
        11            // login page is always permitted
        12             super.process(request,response);
        13
        14        } else {
        15              if ( ! AuthUtils.permitted(subject, perm) ) {
        16              // subject is not permitted; redirect to error page
        17       } else {
        18                 super.process(request,response);
        19             }
        20         }
        21    }


    Lines 6 and 7 get needed information including the Permission that represents the URL the user is trying to access (PermissionFactory is a factory class that returns the appropriate Permission), and the cached Subject.

    On lines 8-14, the case of the unauthenticated user is handled by redirecting the user to the login page, where access is always allowed (line 12). The reason that this can't be handled by the wildcard grant in Example 8 is that the Subject is null in this case. If the program catches this and creates a new Subject, that Subject still has no Principals and thus is still denied access. For a production system, it's conceivable this case could be handled with an anonymous Principal.

    If this is a request for any other resource than the login page, on line 15 the access control class is called. Access is either disallowed, or the process method of the superclass is called.

    The ActionServlet should not know about the particulars of the access control; this should instead be handled by a business class. For this example, such a business class was written; it is examined in the next section.

     

    The Access Control Class
    This class is similar to the java.security.AccessController class [19], and ends defers to that class eventually (via the SecurityManager). The logic in the class can then be reused anywhere that authorization is needed. The class will basically check whether a Subject has a given Permission.

    Example 13. An Abridged Permission Checking Class

         1 package com.xor.auth;
         2
         3 import java.security.*;
         4 import javax.security.auth.*;
         5 import java.util.*;
         6
         7 public class AuthUtils {
         8
         9     static public boolean permitted(Subject subj, final Permission p) {
        10         final SecurityManager sm;
        11         if (System.getSecurityManager() == null) {
        12             sm = new SecurityManager();
        13         } else {
        14             sm = System.getSecurityManager();
        15         }
        16         try {
        17             Subject.doAsPrivileged(subj, new PrivilegedExceptionAction() {
        18                 public Object run() {
        19                     sm.checkPermission(p);
        20                     return null;
        21                 }
        22                 },null);
        23             return true;
        24         } catch (AccessControlException ace) {
        25             return false;
        26         } catch (PrivilegedActionException pae) {
        27             return false;
        28         }
        29     }
        30 }

    The example has had all logging, error checking and comments removed for brevity. Production code should, for example, test to see that neither the Permission nor the Subject are null.

    Lines 10-15 create a SecurityManager. If the application happens to be one of the rare java applications that run with a SecurityManager installed, then that SecurityManager should be used. If not, a new one is created to check the permissions on line 12.

    Lines 16-23 do the actual permission check. If the Subject does not have a Principal which has been granted the Permission, the SecurityManager will throw an exception. For reasons of cleanliness and clarity, this exception is caught and converted to false, which is returned to the calling class. Otherwise, the action is allowed, and true is returned.

    The null on line 22 is very important; it tells the SecurityManager to consider this resource access in an isolated context, ignoring the permissions of code currently on the execution stack. For further information, see chapter 5 of Java Security.

    Note: If the application is running with a SecurityManager enabled, make certain that the AuthUtils class has been granted the doAsPrivileged AuthPermission in the standard java security policy file. Otherwise, this permission checker will not be able to run; a SecurityException will be thrown when line 17 is reached.


    Conclusion
    The authentication piece of JAAS seems fairly bulletproof. The idea of pluggable authentication modules is great and the developer can leverage a number of existing modules to ease development.

    Using JAAS to leverage the SecurityManager for authorization is entirely commensurate with the java security model. There are resources that only certain users with certain principals should be able to see. Rather than reinvent an access control layer, it makes sense to use the one that java already provides.

    However, there are some caveats. This was an extremely simplistic example, and the reader will have noted the number of places where parts of the system need to be replaced to create a production system; these include a new controller, permission class, and policy implementation. In addition, this permission model does not map well to the concept of different protocols used to view a URL.

     


    Definitions
    user: a real world entity. It can be another computer system or a human being. This is not represented by an object.


    subject: the user as seen by the web application. Subject is the class that represents this concept.


    principal: one view of the subject. The API states that it "represents the abstract notion of a principal, which can be used to represent any entity, such as an individual, a corporation, and a login id A Principal is a class that represents a principal" [7]. A principal can be thought of as a role or a group, but those terms have special meaning in J2EE (in the servlet container, for one).


    resource: anything in a system to which unlimited access is not granted to all.


    permission: access to a resource. The Permission class represents a triplet of resource, action and name. Permissions can be granted to a Principal.


    Authentication: the act of verifying that a user is a subject and granting the user certain principals; "who you are."


    Authorization: the act of verifying that a user is allowed to access a certain resource; "what you may do."


    Authentication module: one method of authenticating a user. Examples include verifying against /etc/passwd and examining the contents of a cookie.


    Authentication scheme: a combination of authentication modules.



    my java 2005-08-17 17:38 鍙戣〃璇勮
    ]]>
    Authenticate a Servlet App using Windows Passwords?http://www.tkk7.com/lmsun/articles/10362.htmlmy javamy javaWed, 17 Aug 2005 09:28:00 GMThttp://www.tkk7.com/lmsun/articles/10362.htmlhttp://www.tkk7.com/lmsun/comments/10362.htmlhttp://www.tkk7.com/lmsun/articles/10362.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10362.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10362.html

    Current instructions for configuring Tomcat for JAAS-based Windows authentication.
    This is the solution for my previous post.

    Samba NTLM Authentication: (Get it here.) This package configures exactly as described. I used the example servlet (NtlmHttpAuthExample) included with the package and set up the filter as in the docs. The web.xml file is here.

    Notes: I tested on my home (windows) network which does not have a domain controller; I used workgroup authentication and did not test against a PDC. So YMMV.

    There are two main drawbacks of this approach:

    The first is that the jcifs filter (as currently implemented) does not return group membership information. If your servlet app uses security roles and security constraints, this is a problem since you need some way of getting a user鈥檚 group memberships (so the container can map them to security roles). You could get probably around this problem by extending the jcifs library to return group information; this is more work than I planned to invest. Another approach would be to create a second filter that maps user names to group memberships, perhaps using the tomcat-users.xml file. This would be cumbersome and proprietary, but it would probably work.

    The second drawback is that NTLM authentication is deprecated in the Windows world. Windows 2000 and 2003 use Kerberos authentication, and only fall back on NTLM when they have to.

    For these reasons, I abandoned the Samba NTLM approach and looked at the Tagish / JAAS approach.

    JAAS with Tagish SSPI JAAS provider: JAAS with the Tagish SSPI-based login module is the way to go. The Tagish login module is based on the Windows SSPI API, which provides an authentication service for distributed environments using the best available protocol; i.e. it uses Kerberos when that is available and transparently falls back on NTLM when Kerbos is not available. In addition, SSPI returns the group membership information, which is necessary for servlet apps that use security roles and security constraints.

    The first step in setting this up is to configure the Tagish login module according to the instructions that come with it. In a nutshell, the steps are as follows:

    • Put NTSystem.dll somewhere on your path
    • Put tagishauth.jar on your classpath
    • Copy the tagish.login file to $JAVA_HOME/jre/lib/security
    • Add this line:
      login.config.url.1=file:${java.home}/lib/security/tagish.login
      to your java.security file (in $JAVA_HOME/jre/lib/security)

    You can test the configuration using the login.bat file that comes with the Tagish package. If you are on a workgroup, you may need to edit a registry setting to get network authentication to work properly. (I had to.) See this Microsoft KB article for more information; apparently, Windows XP has a 鈥淔orceGuest鈥?parameter that forces all network logins for a workgroup to use the guest account.

    The second step is to configure Tomcat to use this login module. Here are the steps I used to configure it in Tomcat 5.0.16. Note that the first 4 steps are the same ones for setting up the Tagish login module, just tweaked a little for Tomcat.

    • Copy NTSystem.dll to the Tomcat5 bin directory
    • Copy tagishauth.jar to the Tomcat5 common/lib directory
    • Copy tagish.login to the $JAVA_HOME/jre/lib/security directory. I set the defaultDomain parameter to the name of my server since I鈥檓 on a workgroup.
    • Add this line:
      login.config.url.1=file:${java.home}/lib/security/tagish.login
      to your java.security file (in $JAVA_HOME/jre/lib/security)
    • Configure a JAAS Realm in your Tomcat server.xml file using the following element:
      <Realm className=鈥漮rg.apache.catalina.realm.JAASRealm鈥?debug=鈥?0鈥?BR>   appName=鈥漀TLogin鈥?BR>   userClassNames=鈥漜om.tagish.auth.win32.typed.NTUserPrincipal鈥?BR>   roleClassNames=鈥漜om.tagish.auth.win32.typed.NTGroupPrincipal鈥?/>

    The most important thing to remember is that the userClassNames and roleClassNames have to be exactly the same names as the classes that the Tagish login module returns. This is necessary because the Tomcat JAASRealm class compares the classnames of the principal objects with the class names given in the realm configuration. If they do not match exactly, they are ignored.

    You can test the configuration using the same NtlmHttpAuthExample servlet that we used to test Samba NTLM. You need a different web.xml that uses security roles; the one I used is here. For this to work, you have to login using an account that is a member of the TESTGROUP group.

    To debug it, I had to get log4j working with Tomcat5, which is an adventure in itself. It turns out that the instructions in the Tomcat5 FAQ are incomplete; you need to add commons-logging.jar to common/lib in addition to all the other steps. If you run into trouble, getting log4j debug messages out of the org.apache.catalina.realm package should tell you what is going wrong.

    16 Responses to 鈥淗ow To Authenticate a Servlet App with Windows Passwords鈥?/H3>
    1. carmen Says:

      hi,
      I cannot get tagish working! I don鈥檛 know what I鈥檓 doing wrong. Someone can help me please? I鈥檝e followed the list above step by step :(
      System: Struts and tomcat on W2000 professional (but also tried same config on W2000 server and it doesn鈥檛 work either)
      Thanks

      stack trace:

      19-Jul-2004 17:17:12 org.apache.catalina.realm.JAASRealm authenticate
      WARNING: Login exception authenticating username Administrator
      javax.security.auth.login.LoginException: Error: javax.security.auth.callback.TextInputCallback@da3772 not available to garner authentication information from the user
      at com.tagish.auth.win32.NTSystemLogin.login(NTSystemLogin.java:128)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:675)
      at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
      at javax.security.auth.login.LoginContext.login(LoginContext.java:534)
      at org.apache.catalina.realm.JAASRealm.authenticate(JAASRealm.java:281)
      at org.apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.java:129)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
      at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
      at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
      at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
      at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:793)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:702)
      at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:571)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:644)
      at java.lang.Thread.run(Thread.java:534)
      19-Jul-2004 17:20:17 org.apache.coyote.http11.Http11Protocol pause
      INFO: Pausing Coyote HTTP/1.1 on http-8080

    2. Chris Maeda Says:

      I saw this problem; it was caused by a mistake in the config files. Does Tomcat throw an earlier exception that complains about parsing the tagish login config file? If the parse fails, the callback handler will not be initialized.

    3. Manju Panjwani Says:

      I am also facing the same issue.
      WARNING: Login exception authenticating username Administrator
      javax.security.auth.login.LoginException: Error: javax.security.auth.callback.TextInputCallback@da3772 not available to garner authentication information from the user
      at com.tagish.auth.win32.NTSystemLogin.login(NTSystemLogin.java:128)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

      Were you able to resolve the above? Please guide.

    4. Louis A Johannson Says:

      I鈥檝e got the Tagish example working fine where I can use the batch login.bat to test a

      login/authentication. I can also integrate it with JAAS security and have it authenticate me

      against my network in a console application. However, as soon as I try to tie it into

      Tomcat, I get stuck. (I鈥檓 trying an web-app example based on BASIC authentication)

      I think my files are in the correct places (I get different errors when they鈥檙e missing) and

      I can make my tomcat example web-app work using a different authentication method (the

      tomcat manager鈥檚 memory-realm user authentication works fine) and I鈥檝e even done the JAAS

      example to replace the security realm of the tomcat manager app with JAAS.

      The problem I鈥檓 getting now is that I get a serious bomb that kills tomcat as soon as I try

      to access the protected directory:

      An unexpected exception has been detected in native code outside the VM.
      Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred at PC=0x7BF6256
      Function=[Unknown.]
      Library=C:\Projects\workspace3\example.Tomcat_NT\lib\NTSystem.dll

      NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

      Current Java thread:
      at com.tagish.auth.win32.NTSystem.logon(Native Method)
      - locked <0x10024d98> (a com.tagish.auth.win32.NTSystem)
      at com.tagish.auth.win32.NTSystemLogin.login(NTSystemLogin.java:134)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      ...

      I鈥檓 really rather at a loss as to why this is happening. It 鈥榝eels鈥?like there is something

      wrong with the tagish module, but if others got it working I really don鈥檛 know. Did you have

      to extend it at all? Or wrap it up in an implemented JAAS interface? (but tagish has done

      that already haven鈥檛 they?)

      Config:
      Tomcat 5.0.27/28
      Eclipse 3.0
      Sysdeo eclipse/tomcat plugin
      J2SDK 1.4.2_05
      Tagish 1.0.3

      I also tried plugging the tagish module straight into a clean tomcat (without using any of

      my code) to replace the security realm of the manager web-app. The error is slightly

      different here:

      7-Sep-2004 12:46:17 AM org.apache.catalina.realm.JAASRealm authenticate
      WARNING: Login exception authenticating username louis
      javax.security.auth.login.LoginException: Error: javax.security.auth.callback.Te
      xtInputCallback@354749 not available to garner authentication information from t
      he user
      at com.tagish.auth.win32.NTSystemLogin.login(NTSystemLogin.java:128)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
      java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
      sorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:675)
      at javax.security.auth.login.LoginContext.access$000(LoginContext.java:1
      29)
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java
      :607)
      at javax.security.auth.login.LoginContext.login(LoginContext.java:534)
      at org.apache.catalina.realm.JAASRealm.authenticate(JAASRealm.java:316)
      at org.apache.catalina.authenticator.BasicAuthenticator.authenticate(Bas
      icAuthenticator.java:129)

      Does anyone have a clean working example in tomcat they鈥檇 be willing to zipup and post?

      My proper email prefix is: louis_a_j
      Suffix: telus.net

    5. Louis A. Johannson Says:

      P.S. As per the following post:
      Tagish and JBOSS
      I鈥檝e tried substituting a default domain into the tagish.login (my workgroup) but that just brought me back to the previous exception which kills tomcat.
      Note: I鈥檝e tried this on both an NT4 domain and on a windows 2000 workgroup with the same results in both.

    6. Louis Johannson Says:

      Sorry, the link I included broke:
      http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3837312#3837312

    7. Aaron Hawkins Says:

      I have the same problem as the #4 comment on this page submited by Louis Johannson. I can authenticate using a console app, but when I try and follow the instructions to authenticate agains Tomcat, my jvm blows up with the same error. It seems that there is a problem with NTSystem.dll. If it is anywhere on my path, my jvm will blow up when I try and use tomcat. If I delete it, then I get errors about it not being found. Has anyone found a solution to this? Any help would be appreciated.

    8. Aaron Hawkins Says:

      I have found the solution to the problem described by post #4. The NTSystem.dll doesn鈥檛 appear to like a null username. When trying to get this to work with Tomcat, if you use Form based authentication, you can avoid sending a null username, and everything works great.

    9. rafal piotrowski Says:

      Hi
      I try to use samba ntlm filter first and I鈥檝e got some problem.
      If I try to open some web page from my web app the internet browser logon dialog always shows.
      How should I configure my Windows XP workstation to eliminate this dialog.

    10. mgr Says:

      Hi,
      I have a question about automatic authentication.

      I have a windows 2003 server with active directory. Tomcats and JAAS libraries are correctly installed and configured. When I try to access to the web site I protected by the realm, a login/password is requiered, and I can access to the web site after authentication.

      My question is: is it possible not to have the login/password dialog box if I access to Web site with a computer that belongs to the domain I create and if i鈥檓 logged with the correct login/password to have access.
      I would automatically enter to the web site as I鈥檓 already authenticated in the Windows session. Is that possible?

      The case is the same if I try locally, on the server. I鈥檓 logged with an account who belongs to the domain, and this account belongs to the group I defined in the active directory and in the web.xml file of the web site. But the system ask me the login/password and don鈥檛 acces directly to the web site.

      Thanks

    11. Mel Riffe Says:

      I鈥檓 starting down this path also and having some troubles. One thing I noticed there is a typo in the instructions. I think you should update the java.security file like so:
      login.config.url.1=file:${java.home}/jre/lib/security/tagish.login

      Plus I added the following to Tagish鈥檚 login.bat:
      -Djava.security.auth.login.config=C:\j2sdk1.4.2_06\jre\lib\security\tagish.login

      Next step鈥uthenticating in Tomcat鈥?/P>

      - Mel

    12. Trinition Says:

      I modified the NTSystemLogin source in the Tagish JAAS module to throw a FailedLoginException for a null username or password,a nd not normal BASIC auth works. I presume the null was blowing up in the Tagish NTSYstem.dll or the call it makes to the Win32 API. I shared my update with the Tagish JAAS author, so I鈥檒l see what he thinks.

    13. vicky Says:

      Hi, I am trying to use tagish with tomcat 5.0.27 and exactly getting all the same problems mentioned by others. Is there any clear way to use tagish??

      Please advice.
      thanks
      aks

    14. jh Says:

      does this also work on websphere server?

    15. Kris Dover Says:

      Aaron Hawkins, thanks a million. My tomcat 5.0.28 was also crashing with the Basic authentication and i noticed the username null entries in the stdout.log and wondered if that was causing it, but never made an attempt to resolve it using form base authentication until reading your message. seemed very unusual that tomcat鈥檚 basic authentication was returning nulls even when the correct username and password were entered on the first try. go figure. Trinition, i haven鈥檛 seen an update with your recommended fix, so i might just hack the java code myself. thanks.

    16. Joe Says:

      The TextInputCallback is issued when you do not have a defaultdomain=鈥漼ourdomain鈥?in your tagish.login file, there is no way for a TextInputCallback to work through the servlet, the source should be changed so that it could parse the domain from the username callback if no default domain is specified, however some people may want to have a text callback for applications instead of servlets.

      The Null username does indeed crash the NTSystem.dll, simply change the login attempt:

      succeeded = false
      ntSystem.logon(username, password, domain); // may throw
      succeeded = true;

      to:

      succeeded = false;
      if (username == null || password == null) {
      throw new LoginException("Error: " + username == null ? "username" : "password" + ", null, not allowed");
      }
      ntSystem.logon(username, password, domain); // may throw
      succeeded = true;

      and recompile the tagish src to a jar file, deploying it in the Tomcat/bin directory like explained above and everything will work correctly even with Basic auth.

      This is great and all, but I don鈥檛 see how tagish is using NTLM, unless you mean it is talking to my domain to get my roles using kerberos or NTLM, it does not however provide the transparent login that jCIFS does. I looked throught the tagish source and don鈥檛 see anything in there either, did I misread your article or did I overlook something?



    my java 2005-08-17 17:28 鍙戣〃璇勮
    ]]>Tagish.net JAAS LoginModuleshttp://www.tkk7.com/lmsun/articles/10344.htmlmy javamy javaWed, 17 Aug 2005 07:48:00 GMThttp://www.tkk7.com/lmsun/articles/10344.htmlhttp://www.tkk7.com/lmsun/comments/10344.htmlhttp://www.tkk7.com/lmsun/articles/10344.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10344.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10344.html

    榪欐湡鍏堜粙緇嶆湁鍏?Authentication 鐨勯儴鍒? JAAS 鎻愪緵浜?PAM ( Pluggable Authentication Module ) 鐨勬ā鍧? 鍙?浠ラ氳繃鏍囧噯鐨?API 寤虹珛灞炰簬鑷繁鐨?LoginModule, 鏍規(guī)嵁 stackable 鍘熺悊, 榪涜岀浉鍏崇浉鍏崇殑韜喚楠岃瘉紼嬪簭, 杈懼埌 SSO ( Single Sign-On ) 鐨?鐩殑.


    SECTION 02 JAAS 涓嚑涓瘮杈冨父瑙佺殑 classes

    鏈妭璇︾粏瑙h璇峰弬鑰?http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html


    鏅氬璞?
    • Subject
    • Principals
    • Credentials
    韜喚楠岃瘉鐩稿叧鐨勫璞?
    • LoginContext
    • LoginModule
    • CallbackHandler
    • Callback
    鏉冮檺綆℃帶鐩稿叧鐨勫璞?
    • Policy
    • AuthPermission
    • PrivateCredentialPermission

    SECTION 03 Tagish.net 鐨?LoginModules

    鐜板湪鍦扮偣 http://free.tagish.net/jaas/


    鏈鏂扮増鏈?1.0.3


    鐩墠 tagish.net 鎻愪緵浜?jiǎn)鍑牽U?LoginModules, 鍖呭惈浜?jiǎn)顪侯?
    • com.tagish.auth.DBLogin
    • com.tagish.auth.FileLogin
    • com.tagish.auth.win32.NTSystemLogin
    涓鑸漢澶у姣旇緝鐔熸?zhèn)夋暟鎹簱鎿嶄? 棣栧厛鍏堝緩绔嬩竴涓?login.config, 鍏у涓?
    JAASLogin
    {
    	com.tagish.auth.DBLogin required 
    	dbDriver="sun.jdbc.odbc.JdbcOdbcDriver" dbURL="jdbc:odbc:DBLogin";
    };
    
    灝?Principal 璁劇疆涓?com.tagish.auth.TypedPrincipal ( 濡傛灉鏄?NTSystemLogin 鍒欒緗負(fù) com.tagish.auth.win32.NTPrincipal ). 鎺ョ潃, 浣犵殑鏁版嵁搴撻渶瑕佷竴浜涜〃,

    鍒嗗埆鍦ㄦ暟鎹簱鍏ц緗畬鎴? 褰撲綘鍚姩浣犵殑紼嬪簭鐨勬椂鍊? 浣犻渶瑕佸湪 classpath 涓緗浉鍏崇殑 JDBC Driver, 璁?SecurityManager 鍙傝?login.config, 鍘昏皟鐢?DBLogin api, 鍙栧緱鍚堟硶鎴栦笉鍚堟硶鐨勭姸鎬?


    SECTION 04 鍏充簬 PAM stack

        Login2 {
           sample.SampleLoginModule required;
           com.sun.security.auth.module.NTLoginModule sufficient;
           com.foo.SmartCard requisite debug=true;
           com.foo.Kerberos optional debug=true;
        };
    
    鍋囧鎴戜滑鐢?Login2 鐨勮繖縐嶇櫥闄唖tack, 鍙互璁劇疆 required, sufficient, requisite, optional 鍥涚鐘舵?
    • required : 楠岃瘉蹇呴』鎴愬姛, 浣嗘槸涓嶈鎴愬姛鎴栧け璐ラ兘緇х畫(huà)鎵ц涓嬮潰鐨勭櫥闄嗘ā鍧? 鎵ц鎵鏈変箣鍚庢墠涓熷嚭楠岃瘉澶辮觸.
    • requisite : 楠岃瘉蹇呴』鎴愬姛, 浣嗘槸澶辮觸灝遍┈涓婂洖鍘諱笉鍋氬叾浠栭獙璇? 蹇呴』鎴愬姛鎵嶇戶緇墽琛屼笅闈㈢殑鐧婚檰妯″潡.
    • sufficient : 楠岃瘉鍙互涓嶈鎴愬姛, 浣嗘槸鎴愬姛浜?jiǎn)灏遍┈涓婂洖鍘讳笉鍋氬叾浠栭獙璇? 澶辮觸鍙互緇х畫(huà)鎵ц鍏朵粬鐨勭櫥闄嗘ā鍧?
    • optional : 楠岃瘉鍙互涓嶈鎴愬姛, 浣嗘槸涓嶈鎴愬姛鎴栧け璐ラ兘緇х畫(huà)鎵ц涓嬮潰鐨勭櫥闄嗘ā鍧?
    鎵浠? Login2 鐨勭櫥闄? 棣栧厛鎴戜滑浼?xì)鍏堜娇鐢?sample.SampleLoginModule 鏉ラ獙璇?

    涓嶈鎴愬姛鎴栧け璐ラ兘浼?xì)鎵ц?com.sun.security.auth.module.NTLoginModule,

    濡傛灉 NTLoginModule 楠岃瘉鎴愬姛, 鍥犱負(fù)鏄?sufficient, 緋葷粺灝辮瀹氳繖涓漢鏄悎娉曠殑浣跨敤鑰?

    褰?NTLoginModule 楠岃瘉澶辮觸, 灝變細(xì)榪涜 com.foo.SmartCard 鐨勯獙璇?

    濡傛灉 SmartCard 楠岃瘉澶辮觸, 灝辯洿鎺ュ鍛婁綘涓嶆槸鍚堟硶鐨勪嬌鐢ㄨ?

    濡傛灉 SmartCard 楠岃瘉鎴愬姛, 灝辯戶緇埌 Kerberos 鐨勯獙璇佹ā鍧?

    鍥犱負(fù) Kerberos 鏄睘浜?optional, 鎵浠ユ牴鏈韜喚楠岃瘉鐨勭粨鏋滄病鏈夊獎(jiǎng)鍝?

    Login2 楠岃瘉鐨勫悇縐嶇姸鍐靛垪琛?/B>
    SampleLoginModule required pass pass pass pass fail fail fail fail
    NTLoginModule sufficient pass fail fail fail pass fail fail fail
    SmartCard requisite * pass pass fail * pass pass fail
    Kerberos optional * pass fail * * pass fail *
    Overall Authentication pass pass pass fail fail fail fail fail
    * = 涓嶄細(xì)琚墽琛? 鐩存帴鍥炲簲楠岃瘉鎴愭垨澶辮觸


    SECTION 05 濂楃敤 Tomcat 4/5 鐨?JAASRealm

    寤虹珛 login.config 鏀懼埌 $CATALINA_HOME/conf/ 涔嬩腑, 鑼冧緥閲囩敤 MS SQLServer, jTds.sf.net 鐨?jdbc driver
    JAASLoginModule
    {
    com.tagish.auth.DBLogin required dbDriver="net.sourceforge.jtds.jdbc.Driver" 
    dbURL="jdbc:jtds:sqlserver://localhost:1433/JAASDB" 
    dbUser="sa" 
    dbPassword="sa_password"
    userTable="Users"
    roleTable="Roles"
    roleMapTable="RoleMap";
    };
    
    鍦?tomcat 鍚姩鑴氭湰涓姞鍏?BR>顧☆棸 JAVA_OPTS=-Djava.security.auth.login.config==C:\tomcat4\conf\login.config 騫朵笖淇敼 server.xml, 璁?appName 鍘誨搴?login.config 涓殑 JAASLoginModule, 浠ュ強(qiáng)璁劇疆 User/Group 鐩稿叧鐨?Principal
    <Realm className="org.apache.catalina.realm.JAASRealm"                 
    			 appName="JAASLoginModule"
    		 userClassNames="com.tagish.auth.TypedPrincipal"       
    		 roleClassNames="com.tagish.auth.TypedPrincipal" 
    			debug="99"/>
    
    鏈鍚庤緗?web.xml 涓殑 login-config 浠ュ強(qiáng)瑕佷繚鎶ょ殑鏁版嵁, 渚嬪
    		
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>User Protected</web-resource-name>
          <url-pattern>/protected/*</url-pattern>
          <url-pattern>/protected.jsp</url-pattern>
        </web-resource-collection>
        <auth-constraint>
           <role-name>user</role-name>
        </auth-constraint>
      </security-constraint>
      <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>MyJAASRealm</realm-name>
      </login-config>
    
    SECTION 06 緇撹

    JAAS 闄や簡(jiǎn)鍦ㄤ竴鑸?Desktop Application 搴旂敤涔嬪, 瀵?J2EE 鏀寔灝嗕細(xì)鏄竴涓富嫻? 鏃犺鏄?JSR 196: Java Authentication Service Provider Interface for Containers 榪?鏄?JSR 115: Java Authorization Contract for Containers ( 宸茬粡綰沖叆 J2EE 1.4 涔嬩腑 ) 閮芥槸瀵?container 鎻愪緵鑰呰姹傛爣鍑嗙殑 provider 鐣岄潰, 鍥犳, 灝嗘潵寮鍙戠浉鍏崇殑紼嬪簭鏈濂借兘澶熼伒寰?JAAS, 鍦ㄥ紓鏋勫鉤鍙扮殑鏁村悎 涓? 鎵嶈兘鍏峰瀹屾暣鐨勭浉瀹規(guī)?

    my java 2005-08-17 15:48 鍙戣〃璇勮
    ]]>
    WEB搴旂敤涓殑鍩烘湰韜喚楠岃瘉鍜岃〃鍗曡韓浠介獙璇?涓枃)http://www.tkk7.com/lmsun/articles/10307.htmlmy javamy javaWed, 17 Aug 2005 02:07:00 GMThttp://www.tkk7.com/lmsun/articles/10307.htmlhttp://www.tkk7.com/lmsun/comments/10307.htmlhttp://www.tkk7.com/lmsun/articles/10307.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10307.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10307.htmlTranslated by Caiyi0903(Willpower)錛?004.4.23

    鍦ㄤ換浣曚竴縐峎EB搴旂敤寮鍙戜腑錛屼笉璁哄ぇ涓皬瑙勬ā鐨勶紝姣忎釜寮鍙戣呴兘浼?xì)閬囧堫C竴浜涢渶瑕佷繚鎶ょ▼搴忔暟鎹殑闂錛屾秹鍙?qiáng)鍒扮敤鎴风殑LOGIN ID鍜孭ASSWORD銆傞偅涔堝浣曟墽琛岄獙璇佹柟寮忔洿濂藉憿錛熷疄闄呬笂錛屾湁寰堝鏂瑰紡鏉ュ疄鐜般傚湪鏈枃閲岋紝鎴戜滑涓嶄細(xì)鎶婃墍鏈夌殑楠岃瘉鏂規(guī)硶閮借冭檻鍒幫紝鎴戜滑鐨勭洰鐨勬槸璁╀綘瀛︿細(xì)濡備綍浠ユ渶綆鍗曟渶鏂逛究鐨勯獙璇佹柟娉曟潵瀹屾垚銆備笅闈㈠皢璁ㄨ鍩烘湰鐨勶紙BASIC錛夊拰鍩轟簬琛ㄥ崟鐨勶紙F(tuán)ORM-BASED錛夐獙璇佹柟寮忋傛垜浠冭檻浣跨敤TOMCAT浣滀負(fù)WEB SERVER錛屽畠閫氳繃server.xml鍜寃eb.xml鏂囦歡鎻愪緵鍩烘湰鐨勫拰鍩轟簬琛ㄥ崟鐨勯獙璇併侸SP欏甸潰涓殑j_security_check 琛ㄥ崟(for FORM-based) 闇瑕佷袱涓弬鏁幫細(xì)j_username鍜宩_password銆傚畠浠寚瀹氫簡(jiǎn)鍦⊿QL鏁版嵁搴撲腑鐨勭櫥闄嗚鑹層備綘鑳藉鐪嬪埌錛屽畠鐨勫脊鎬у寲錛屽彲鐢ㄦу拰蹇呰鎬с?/P>

    絎竴姝ワ紝鎴戜滑瑕佷笅杞絋OMCAT鍜孧YSQL錛屽墠鑰呯敤鏉ュ仛WEB SERVER錛屽悗鑰呯敤鏉ュ仛SQL SERVER銆傝繕瑕佷笅杞絁DBCRealm宸ュ叿錛屽畠鍦═OMCAT涓嬌鐢紝鐢ㄦ潵鍋歁YSQL榪炴帴鍣紝榪炴帴MYSQL鏁版嵁搴撶殑銆?/P>

    鎴戜滑鍋囪浣犲凡緇忓畨瑁呬簡(jiǎn)TOMCAT鍜孧YSQL錛岄偅涔堟垜浠紑濮嬩粠SERVER鐨勯厤緗叆鎵嬩簡(jiǎn)銆傚綋鐒?dòng)灱屼綘杩橀渶瑕佸畨瑁匤AVA鐨凪YSQL榪炴帴椹卞姩錛屾垜寮虹儓寤鴻鍙嬌鐢ㄧǔ瀹氱殑椹卞姩鐗堟湰錛屽洜涓哄湪鏈変簺鎯呭喌涓嬶紝alpha/beta鐗堟湰鐨勯┍鍔ㄤ笉鑳芥甯稿伐浣溿?/P>

    涓嬮潰鎴戜滑鏉ユ搷浣淪QL鏁版嵁搴撱傝佸疄璇達(dá)紝MYSQL鍜孴OMCAT鏄浉褰撳ソ鐨勫伐鍏鳳紝瀹冧滑閮芥槸璺ㄥ鉤鍙扮殑錛屼笉綆′綘鐨勬搷浣滅郴緇熸槸WINDOWS榪樻槸綾諱技UNIX/LINUX鐨勶紝瀹冧滑閮借兘姝e父榪愯銆傚洜姝わ紝涓嶈榪愯鐜錛屽畠浠殑閰嶇疆榪囩▼閮芥槸緇濆涓鏍風(fēng)殑銆?/P>

    MySQL
    鍦ㄥ懡浠よ涓墽琛宮ysql 瀹㈡埛绔懡浠わ紝鐒跺悗杈撳叆錛?/P>

    create database weblogin;
    榪欎釜灝嗕負(fù)浣犲垱寤轟竴涓獁eblogin鏁版嵁搴擄紝瀹冨皢淇濆瓨鐢ㄦ埛鍚嶅拰瀵嗙爜浠ュ強(qiáng)瑙掕壊絳変竴鍒囦俊鎭備綘瀵規(guī)暟鎹簱鎵鍋氱殑浠諱綍鏀瑰彉閮戒細(xì)鐩存帴绔嬪嵆鍙嶆槧鍑烘潵銆傛瘮濡傝娣誨姞鐢ㄦ埛錛屾敼鍙樼敤鎴峰瘑鐮佸拰瑙掕壊絳夈?/P>


    create table users (
       login varchar (15) not null,
       pass varchar (15) not null,
       primary key (login)
    );

    鎴戜滑鍒涘緩涓涓猽sers琛ㄧ敤鏉ヤ繚瀛樼敤鎴風(fēng)殑LOGIN鍜孭ASSWORD錛?/P>


    create tables groups (
       login varchar (15) not null,
       group varchar (15) not null,
       primary key (login, group)
    );

    濡備綘鐪嬪埌鐨勶紝鎴戜滑瑕佸湪group琛ㄩ噷淇濆瓨login灞炰簬鍝釜group鐨勪俊鎭備笅闈紝鎴戜滑瑕佹彃浜庝竴浜涙暟鎹敤鏉ユ祴璇曚嬌鐢紝騫跺畬鎴怣YSQL鐨勯厤緗伐浣滐細(xì)

    insert into users  ('green', 'testpwd');
    insert into groups ('green', 'testgroup');


    鐜板湪錛屾垜浠垱寤轟簡(jiǎn)涓涓敤鎴峰彨green錛屼粬鐨勫瘑鐮佹槸testpwd錛屼粬灞炰簬testgroup榪欎釜鐢ㄦ埛緇勩傛帴鐫錛岃疆鍒癟OMCAT鐨勯厤緗簡(jiǎn)銆?/P>

    Tomcat
    TOMCAT鏈韓騫舵病鏈夎兘鍔涙搷浣滄暟鎹簱鏉ュ疄鐜拌韓浠介獙璇併備絾鏄彲浠ヤ緷闈燡DBCRealm銆備笅闈㈡垜浠潵浣跨敤瀹冦?/P>

    涓嬮潰鎴戜滑浠嶵OMCAT鐨刓conf\server.xml鏂囦歡鏉ュ紑濮嬫垜浠殑閰嶇疆銆傛墦寮榪欎釜鏂囦歡騫舵壘鍒頒笅闈㈢殑鍐呭:

    <Realm className="org.apache.catalina.realm.MemoryRealm" />
    鍒犻櫎榪欎竴琛岋紝鎴栬呯敤<!-- ... --> 娉ㄩ噴鎺夊畠,鎴戜滑瑕佷嬌鐢↗DBCRealm銆傛墍浠ヨ緭鍏ヤ笅闈㈢殑鍐呭:


    <Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
       driverName="org.gjt.mm.mysql.Driver"
       connectionURL="jdbc:mysql://localhost/weblogin?user=test&password=test"
       userTable="users" userNameCol="login" userCredCol="pass"
       userRoleTable="groups" roleNameCol="group" />

    涓嬮潰鎴戜滑瀵筬ield鍙傛暟鍋氳緇嗚瑙?

    debug鈥旇繖鏄垜浠緗殑debug鍙傛暟錛屾暟瀛楄秺楂樻樉紺轟俊鎭秺璇︾粏銆?
    driverName鈥旇繖涓槸MYSQL椹卞姩鐨勫悕瀛椼傝紜繚榪欎釜椹卞姩鐨凧AR鍖呭湪TOMCAT鐨凜LASSPATH涓兘澶熸壘鍒板畠銆?
    connectionURL鈥旇繖涓槸鐢ㄦ潵寤虹珛JDBC榪炴帴鐨勬暟鎹簱URL銆傚湪榪欎釜field閲岋紝weblogin鏄垜浠暟鎹簱鐨勫悕瀛椼倁ser鍜宲assword 鏄垜浠櫥闄嗘暟鎹簱鐨勭敤鎴鋒暟鎹?
    userTable鈥斾竴涓畾涔夋湁userNameCol鍜寀serCredCol瀛楁鐨勮〃銆?
    userNameCol鍜寀serCredCol鈥攗sers琛ㄩ噷瀹氫箟鐨刲ogin鍜宲ass銆?
    鐜板湪錛屾垜浠畬鎴愪簡(jiǎn)閰嶇疆榪囩▼銆備笅闈紝鎴戜滑瑕侀厤緗甒EB搴旂敤紼嬪簭鏉ヨ榪欐牱涓涓韓浠介獙璇佹柟寮忎繚鎶よ搗鏉ャ傛垜浠涓句袱涓緥瀛愩傛渶綆鍗曠殑鏄熀鏈韓浠介獙璇佹柟寮忥紝鐒跺悗灝辨槸鍩轟簬琛ㄥ崟鐨勮韓浠介獙璇併傚湪絎竴縐嶆儏鍐甸噷錛屾垜浠皾璇曡闂彈淇濇姢鐨勬暟鎹紝灝嗕細(xì)鏈変竴涓狿OP-UP紿楀彛寮瑰嚭鎻愮ず浣犺緭鍏ヤ綘鐨刲ogin鍜宲assword銆傚湪絎簩縐嶆儏鍐甸噷錛屾垜浠細(xì)閫氳繃欏甸潰鐨勬柟寮忔潵璁╀綘閫氳繃韜喚楠岃瘉銆傝繖涓〉闈㈢殑鍐呭鍙互鏄換鎰忕殑錛岃繖涓彇鍐充簬浣犺浣跨敤鎬庝箞鏍風(fēng)殑楠岃瘉鏂瑰紡浜?jiǎn)銆?/P>

    鍩烘湰韜喚楠岃瘉鏂瑰紡錛圔ASIC authorization method錛?BR>鎴戜滑鍋囪搴旂敤紼嬪簭鍦═OMCAT鐨刓webapps\webdemo, 鎴戜滑瑕佷繚鎶ゆ墍鏈夊湪admin 瀛愮洰褰曢噷鐨勬枃浠躲傛垜浠繀欏繪墦寮瀹冪殑\webapps\webdemo\WEB-INF\web.xml鏂囦歡錛岃緭鍏ヤ笅鍒楀唴瀹?


    <security-constraint>
       <web-resource-collection>
          <web-resource-name>Web Demo</web-resource-name>
          <url-pattern>/admin/*</url-pattern>
       </web-resource-collection>
       <auth-constraint>
          <role-name>testgroup</role-name>
       </auth-constraint>
    </security-constraint>
    <login-config>
       <auth-method>BASIC</auth-method>
       <realm-name>Web Demo</realm-name>
    </login-config>

    璁╂垜浠潵鐪嬬湅鍒氭墠杈撳叆鐨勫唴瀹廣傛垜浠負(fù)搴旂敤紼嬪簭鍒涘緩浜?jiǎn)涓涓獁eb-resource-name騫舵槧灝勫埌l(fā)ogin-config 銆傛垜浠繕瀹氫箟浜?jiǎn)url-pattern, 瀹冩寚鏄庝綘鍙椾繚鎶ょ▼搴忕殑璺緞銆傚湪login-conf涓紝鎴戜滑瀹氫箟浜?jiǎn)涓涓狟ASIC auth-method銆?/P>

    寰堢畝鍗曪紝瀵瑰悧錛熶笉瑕佸繕璁頒簡(jiǎn)錛屽湪浣挎敼鍙樼敓鏁堝墠瑕佸仠姝㈠茍閲嶅惎TOMCAT銆?/P>

    琛ㄥ崟韜喚楠岃瘉鏂瑰紡錛團(tuán)ORM-based authorization method錛?BR>瀵逛簬榪欑鏂瑰紡錛屾垜浠粎浠呭彧闇瑕?

    淇敼\webapps\webdemo\WEB-INF\web.xml
    鍒涘緩涓涓櫥闄嗙敤鐨凧SP欏甸潰, 鐢ㄦ埛灝嗗湪榪欓噷鐨凥TML琛ㄥ崟涓緭鍏ヤ粬鐨勭櫥闄咺D鍜屽瘑鐮?
    鍒涘緩涓涓狫SP error欏甸潰錛屼竴鏃﹂獙璇佸け璐ワ紝鐢ㄦ埛灝嗚煩鍒拌欏甸潰
    濡傛灉浣犲厛灝濊瘯浣跨敤BASIC楠岃瘉鏂瑰紡錛屼綘鍙渶瑕佹敼鍙榣ogin-config 涓轟笅闈㈤偅涓孌典唬鐮併傚惁鍒欙紝浣犻渶瑕佽緭鍏ecurity-constraint浠g爜孌點(diǎn)備嬌鐢ㄤ笅闈㈢殑login-config:


    <login-config>
       <auth-method>FORM</auth-method>
       <realm-name>Web Demo</realm-name>
       <form-login-config>
          <form-login-page>/admin/login.jsp</form-login-page>
          <form-error-page>/admin/error.jsp</form-error-page>
       </form-login-config>
    </login-config>

    鎴戜滑璁劇疆琛ㄥ崟鐨刟uth-method騫跺畾涔変簡(jiǎn)form-login-config銆傝繖涓皢浣垮緱TOMCAT浣跨敤 \admin\login.jsp欏甸潰鏉ヨ鐢ㄦ埛鐧婚檰錛屼嬌鐢╘admin\error.jsp欏甸潰鏉ュ鐞嗙櫥闄嗗け璐ャ?/P>

    浣犲彲浠ヤ嬌鐢ㄤ換浣曚綘鎯寵鐨勫嚭閿欎俊鎭傞〉闈㈠敮涓闇瑕佺殑灝辨槸涓嬮潰鐨凥TML琛ㄥ崟鏍囩錛屼綘瑕佹彃鍒伴〉闈腑錛?/P>


    ...
    <form method="POST" action="j_security_check">
       <input type="text" name="j_username">
       <input type="text" name="j_password">
       <input type="submit" value="Log in">
    </form>
    ...

    甯冨眬錛岄鏍鹼紝鎴栧叾浠栨墍鏈変綘鍠滄鐨勩傝繖涓猠rror欏甸潰鑳藉鍋氭垚浠諱綍浣犳兂瑕佺殑銆傛棤闈炲氨鏄氱煡鐢ㄦ埛錛岄獙璇佸け璐ヤ簡(jiǎn)銆?/P>

    OK錛屽叏閮ㄥ畬鎴愪簡(jiǎn)銆備綘闇瑕佸仠姝㈠拰閲嶅惎涓閬峊OMCAT浣垮緱鏀瑰彉鐢熸晥銆?/P>

    漏 Olexiy Prokhorenko, http://www.7dots.com/resume/
    Co-author: Alexander Prohorenko



    my java 2005-08-17 10:07 鍙戣〃璇勮
    ]]>
    鍒╃敤Tocmat瀹夊叏鍩熷疄鐜板畨鍏ㄨ璇?/title><link>http://www.tkk7.com/lmsun/articles/10304.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Wed, 17 Aug 2005 01:57:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10304.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10304.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10304.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10304.html</trackback:ping><description><![CDATA[<P>瀹夊叏鍩熷姛鑳芥槸Tomcat鍐呯疆鍔熻兘,鍦╫rg.apache.catalina.Realm鎺ュ彛涓0鏄庝簡(jiǎn)鎶婁竴緇勭敤鎴峰悕銆佸彛浠ゅ強(qiáng)鎵鍏寵仈鐨勮鑹查泦鎴愬埌Tocmat涓殑鏂規(guī)硶銆?/P> <P>鍐呭瓨鍩燂細(xì)MemoryRealm 浠嶺ML鏂囦歡涓鍙栧畨鍏ㄩ獙璇佷俊鎭茍瀛樺叆鍐呭瓨?shù)腑銆?BR>JDBC鍩燂細(xì)JDBCRealm 閫氳繃JDBC椹卞姩紼嬪簭璁塊棶瀛樻斁鍦ㄦ暟鎹簱涓殑淇℃伅銆?BR>鏁版嵁婧愬煙錛欴ataSourceRealm 閫氳繃JDBC鏁版嵁婧愯闂瓨鏀懼湪鏁版嵁搴撲腑鐨勪俊鎭?BR>JNDI鍩燂細(xì)JNDIRealm 閫氳繃JNDI provider璁塊棶瀛樻斁鍦ㄥ熀浜嶭DAP鐨勭洰褰曟湇鍔″櫒涓殑瀹夊叏楠岃瘉淇℃伅銆?/P> <P>璁劇疆璧勬簮瀹夊叏綰︽潫</P> <P>鍦╳eb.xml涓姞鍏?lt;security-constraint>鍏冪礌</P> <P><security-constraint><BR>銆<display-name>MZT</display-name><BR>銆<web-resource-collection><BR>銆銆銆<web-resource-name>protected test</web-resource-name><BR>銆銆銆<url-pattern>/test/*</url-pattern><BR>銆銆銆<http-method>POST</http-method><BR>銆銆銆<http-method>GET</http-method><BR>銆</web-resource-collection><BR>銆<auth-constraint><BR>銆銆<role-name>mztadmin</role-name><BR>銆</auth-constraint><BR></security-constraint><BR><login-config><BR>銆<auth-method>BASIC</auth-method><BR>銆<realm-name>test realm</realm-name><BR></login-config></P> <P><BR>璁劇疆JDBC鍩?/P> <P><Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"<BR>driverName="org.gjt.mm.mysql.Driver"<BR>connectionURL="jdbc:mysql://localhost/mzt"<BR>connectionName="root" connectionPassword=""<BR>userTable="users" userNameCol="user_name" userCredCol="user_pass"<BR>userRoleTable="user_roles" roleNameCol="role_name" /></P> <P><BR><Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"<BR>dataSourceName="jdbc/tomcatusers"<BR>userTable="users" userNameCol="user_name" userCredCol="user_pass"<BR>userRoleTable="user_roles" roleNameCol="role_name"/></P> <P><BR>鍦∕ySQL涓墽琛屼互涓婼QL璇彞:</P> <P>#########</P> <P>#鐢ㄦ埛琛?BR>create table users(<BR>user_name varchar(15) not null primary key,<BR>user_pass varchar(15) not null<BR>);</P> <P>#鐢ㄦ埛瑙掕壊琛?BR>create table user_roles(<BR>user_name varchar(15) not null,<BR>role_name varchar(15) not null,<BR>primary key(user_name, role_name)<BR>);</P> <P>insert into users values('mzt','test');<BR>insert into user_roles values('mzt','mztadmin');<BR></P><img src ="http://www.tkk7.com/lmsun/aggbug/10304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-17 09:57 <a href="http://www.tkk7.com/lmsun/articles/10304.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>鍦╓eb搴旂敤涓嬌鐢˙ASIC鍜屽熀浜嶧orm鐨勯獙璇?/title><link>http://www.tkk7.com/lmsun/articles/10301.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Wed, 17 Aug 2005 01:45:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10301.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10301.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10301.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10301.html</trackback:ping><description><![CDATA[<P>澶у鍙哥┖瑙佹儻浜?jiǎn)鋴社敤鑷忿q殑鏈哄埗榪涜鐢ㄦ埛鐨勯獙璇侊紝鍏跺疄錛孴omcat鏈韓灝卞鐢ㄦ埛鐨勮璇佹彁渚涗簡(jiǎn)鏀寔錛屼嬌鐢═omcat鑷韓鐨勮璇佸姛鑳斤紝鍙渶瑕佽繘琛屼竴浜涚畝鍗曠殑閰嶇疆灝卞彲浠ュ畬鎴愮敤鎴風(fēng)殑楠岃瘉鍔熻兘銆傚鏋滆繕娌℃湁浣跨敤榪囷紝璇昏榪欑瘒鏂囩珷鍚с?/P> <P>BASIC and FORM-based Authorization in Your Web Application<BR>By Olexiy & Alexander Prokhorenko</P> <P>In the development of any, more-or-less big Web application, every developer collides at times with the problem of how to bear certain parts of the application in the protected area and to divide access to them by login and password. How do you carry out authentication? Actually, there are a lot of variants. In this article, we do not present a problem to consider all possibilities; our purpose is to learn how to work with the simplest yet rather convenient method of authorization. We will talk about BASIC and FORM-based authorizations. As a Web server, we will consider Tomcat, which provides BASIC and FORM-based authentication through server.xml and web.xml files; the use of a j_security_check form (for FORM-based) in a JSP page that requires two parameters j_username and j_password; and specifying roles (groups) within the SQL database. As you can see, it's a flexible, useful, and necessary set of capabilities.</P> <P>To begin with, you need to download Tomcat, which we will use as a Web server and MySQL, which we will use as a SQL server. Also, you need to download the JDBCRealm tool which will be used with Tomcat, and the MySQL Connector/J to use with MySQL.</P> <P>We assume you have installed Tomcat and MySQL properly, so we can start right from the server's configuration. Of course, you also need to install the MySQL Connector/J driver, and I strongly recommend using only stable releases of the driver because, in some cases, alpha/beta versions of the driver do not work in the given sheaf.</P> <P>First of all, we will work with the SQL database. Honestly speaking, MySQL, as well as Tomcat, is pretty universal, and doesn't depend on the OS in which you are using it (Windows or Unix-like system), so the process of configuration will be absolutely the same; it doesn't matter where you run it.</P> <P><BR>MySQL</P> <P>Execute the mysql client from the installation binary directory and type:</P> <P>create database weblogin;<BR>This will create the weblogin database in which we will keep user names, passwords, roles?everything. Thus, any changes you have made to the database directly (new users, changed passwords or roles, and so forth) will be reflected immediately.</P> <P><BR>create table users (<BR>   login varchar (15) not null,<BR>   pass varchar (15) not null,<BR>   primary key (login)<BR>);</P> <P>We will keep the user's login and password in this users table.</P> <P><BR>create tables groups (<BR>   login varchar (15) not null,<BR>   group varchar (15) not null,<BR>   primary key (login, group)<BR>);</P> <P>As you can see, we will keep information about which login belongs to which group in this groups table. Let's fill our tables with some test data and finish the process of MySQL configuration:</P> <P><BR>insert into users  ('green', 'testpwd');<BR>insert into groups ('green', 'testgroup');</P> <P>So, we created the user green with the password testpwd in the group testgroup. And now, it's Tomcat's turn to be configured.</P> <P><BR>Tomcat</P> <P>Tomcat itself has no ability to work with the database to carry out authentication. However, there is JDBCRealm for these purposes; we are going to use that.</P> <P>We will start our configuration from Tomcat's \conf\server.xml file. Open this file and find the following string:</P> <P><Realm className="org.apache.catalina.realm.MemoryRealm" /><BR>Remove this line or just comment it by using <!-- ... --> Instead of it, we will use JDBCRealm. Type the following:</P> <P><BR><Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"<BR>   driverName="org.gjt.mm.mysql.Driver"<BR>   connectionURL="jdbc:mysql://localhost/weblogin?user=test&password=test"<BR>   userTable="users" userNameCol="login" userCredCol="pass"<BR>   userRoleTable="groups" roleNameCol="group" /></P> <P>We will consider all mentioned fields in a bit more detail:</P> <P>debug?Here, we set the debug level. A higher number generates more detailed output. <BR>driverName?The name of our MySQL driver. You need to be sure that the driver's JAR file is located in Tomcat's CLASSPATH. <BR>connectionURL?The database URL that is used to establish a JDBC connection. In this field, weblogin is the name of our database; user and password are login data with which you are connecting to the database. In MySQL, such a user is created by default, so you can use it. In case you don't have such a user, you need to create your own user and make it capable of working with your weblogin database. <BR>userTable?A table with at least two fields, defined in userNameCol and userCredCol. <BR>userNameCol and userCredCol?The fields with the name of login field from the users table and pass. <BR>Now, we are at the stage of finishing the configuration process. We need to configure your Web application to be protected with such an authentication. Below, we show examples of two configurations. The simplest is a BASIC authentification method, and a little more original method is a FORM-based one. In the first case at attempting to access the protected area, a pop-up window will appear with the requirement to enter your login and password. In the second case, we will get a page on which we will pass authentification on our defined JSP. The contents of a page can be anything; it should meet only few simple requirements on the contents of a HTML <form> tag. It is up to you what authorization methods you will use.</P> <P><BR>Basic authorization method</P> <P>Let's assume that our Web application is located in Tomcat's \webapps\webdemo, and we need to protect all files placed in the admin subdirectory. We need to open its \webapps\webdemo\WEB-INF\web.xml file and type the following text:</P> <P><BR><security-constraint><BR>   <web-resource-collection><BR>      <web-resource-name>Web Demo</web-resource-name><BR>      <url-pattern>/admin/*</url-pattern><BR>   </web-resource-collection><BR>   <auth-constraint><BR>      <role-name>testgroup</role-name><BR>   </auth-constraint><BR></security-constraint><BR><login-config><BR>   <auth-method>BASIC</auth-method><BR>   <realm-name>Web Demo</realm-name><BR></login-config></P> <P>Let me say a few words about what we just did. We created web-resource-name for our application and mapped login-config to this resource. We defined url-pattern, which has information about which sub-directory of our entire application will be protected, and which role-name is allowed to access the protected area. In login-conf, we defined a BASIC auth-method.</P> <P>Pretty easy, isn't it? Do not forget to stop and re-start Tomcat to make these our changes work.</P> <P> </P> <P>FORM-based authorization method</P> <P>For this method, we will only need to:</P> <P>Modify \webapps\webdemo\WEB-INF\web.xml <BR>Create a login JSP page, on which the user will get a HTML form to enter his login and password <BR>Create a JSP error page that the user will get if an error happened during authorization <BR>So, let's start from the very beginning. In case you tried the BASIC authorization method first, you need just to change the login-config section to the one listed below. Otherwise, you need to type the security-constraint section from the BASIC method (it's absolutely the same), but use the following login-config:</P> <P><BR><login-config><BR>   <auth-method>FORM</auth-method><BR>   <realm-name>Web Demo</realm-name><BR>   <form-login-config><BR>      <form-login-page>/admin/login.jsp</form-login-page><BR>      <form-error-page>/admin/error.jsp</form-error-page><BR>   </form-login-config><BR></login-config></P> <P>We set the FORM's auth-method and defined the form-login-config section; this will force Tomcat to use the \admin\login.jsp page as the page with the HTML form for the user to sign in, and use \admin\error.jsp in case the login failed.</P> <P>You can have any login and error screen you like; the only requirement is that HTML <form> should be the following (to be more exact, it should have fields defined as such):</P> <P><BR>...<BR><form method="POST" action="j_security_check"><BR>   <input type="text" name="j_username"><BR>   <input type="text" name="j_password"><BR>   <input type="submit" value="Log in"><BR></form><BR>...</P> <P>The layout, styles, or whatever else could be anything you like. The error page could be anything you want; you will need to inform the user that there that something is wrong with the authentication.</P> <P>That is all. You need to stop and re-start Tomcat to make these changes work.</P> <P>漏 Olexiy Prokhorenko, <A >http://www.7dots.com/resume/</A><BR>Co-author: Alexander Prohorenko<BR></P><img src ="http://www.tkk7.com/lmsun/aggbug/10301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-17 09:45 <a href="http://www.tkk7.com/lmsun/articles/10301.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>搴旂敤TOMCAT鍩轟簬JDBC鐨勭殑Realm錛?錛?/title><link>http://www.tkk7.com/lmsun/articles/10300.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Wed, 17 Aug 2005 01:41:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10300.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10300.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10300.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10300.html</trackback:ping><description><![CDATA[<P>鎽樿<BR>銆銆Realm鏄竴涓敤鎴鋒暟鎹簱鐨勬蹇碉紝綾諱技浜嶶nix涓殑鐢ㄦ埛緹ょ粍錛屽畠閫氳繃鐢ㄦ埛鍚嶅拰瀵嗙爜鏉ユ爣璇嗕竴涓敤鎴鳳紝榪欎釜鐢ㄦ埛灞炰簬涓瀹氱殑瑙掕壊錛坮ole錛夈傝屼竴涓壒孌婄殑web搴旂敤璧勬簮錛屽彲浠ラ檺瀹氭煇涓鑹茬殑鐢ㄦ埛鎵嶈璁稿彲璁塊棶銆傝繖縐嶈鍙瓥鐣ワ紝浣垮緱web搴旂敤鐨勬暣浣撴潈闄愭帶鍒朵笌搴旂敤緇嗚妭鐩稿墺紱伙紝浠庤岃幏寰楁洿濂界殑鍙厤緗с備笅闈㈡垜浠氳繃姣旇緝甯歌鐨勫熀浜庢暟鎹簱錛屼嬌鐢ㄧ洿鎺DBC榪炴帴鐨凴ealm鐨勯厤緗嬌鐢ㄦ儏鍐碉紝鐪嬬湅瀹冩槸濡備綍瀹炵幇綺楃矑搴︾殑ACL鐨勩?2004-03-13 11:21:34)</P> <P>--------------------------------------------------------------------------------<BR>By lanf</P> <P>搴旂敤TOMCAT鍩轟簬JDBC鐨勭殑Realm 錛?錛?<BR>浣滐紙璇戯級(jí)鑰咃細(xì)Lanf From LinuxAID </P> <P>Realm鏄竴涓敤鎴鋒暟鎹簱鐨勬蹇碉紝綾諱技浜嶶nix涓殑鐢ㄦ埛緹ょ粍錛屽畠閫氳繃鐢ㄦ埛鍚嶅拰瀵嗙爜鏉ユ爣璇嗕竴涓敤鎴鳳紝榪欎釜鐢ㄦ埛灞炰簬涓瀹氱殑瑙掕壊錛坮ole錛夈傝屼竴涓壒孌婄殑web搴旂敤璧勬簮錛屽彲浠ラ檺瀹氭煇涓鑹茬殑鐢ㄦ埛鎵嶈璁稿彲璁塊棶銆傝繖縐嶈鍙瓥鐣ワ紝浣垮緱web搴旂敤鐨勬暣浣撴潈闄愭帶鍒朵笌搴旂敤緇嗚妭鐩稿墺紱伙紝浠庤岃幏寰楁洿濂界殑鍙厤緗с備笅闈㈡垜浠氳繃姣旇緝甯歌鐨勫熀浜庢暟鎹簱錛屼嬌鐢ㄧ洿鎺DBC榪炴帴鐨凴ealm鐨勯厤緗嬌鐢ㄦ儏鍐碉紝鐪嬬湅瀹冩槸濡備綍瀹炵幇綺楃矑搴︾殑ACL鐨勩?</P> <P>JDBCRealm </P> <P>JDBCRealm鏄嬌鐢↗DBC榪炴帴鍏崇郴鏁版嵁搴撶殑涓涓猅omcat 4 Realm鎺ュ彛鐨勫疄鐜般傚畠鍙互鐩存帴浣跨敤浣犵幇鏈夌殑鐢ㄦ埛鏁版嵁搴撹〃錛屾潵鑾峰彇瑙掕壊鐢ㄦ埛鐨勪俊鎭紝瀹屾垚楠岃瘉銆備綘蹇呴』婊¤凍浠ヤ笅鏉′歡錛?/P> <P>蹇呴』鏈変釜鏈夋晥鐨勬暟鎹〃錛岄噷闈㈡湁鎵鏈変綘闇瑕侀氳繃Realm鏉ヨ璇佺殑鐢ㄦ埛銆傝繖寮犺〃蹇呴』鑷沖皯鏈変袱涓瓧孌碉紝鍙互鐢ㄦ潵鏍囩ず鐢ㄦ埛鍚嶅拰瀵嗙爜銆?<BR>闇瑕佹湁涓寮犺〃鏉ユ爣鏄庣敤鎴蜂笌瑙掕壊鐨勫搴斿叧緋伙紝鐢ㄦ埛鍙互鏈変換鎰忎釜瑙掕壊錛屾病鏈夎鑹蹭篃鏄悎娉曠殑錛岃繖鏄拰UNIX鐢ㄦ埛緹ょ粍鐨勪笉鍚屼箣澶勩傚悓鏍瘋繖涓〃涔熼渶瑕佷袱涓瓧孌碉紝鏉ユ槧灝勭敤鎴峰悕涓庤鑹插悕鐨勫搴斿叧緋匯?<BR>鏁版嵁搴撳噯澶?</P> <P>鍦ㄦ垜浠殑渚嬪瓙涓紝鎴戜滑寤轟袱寮犳柊琛ㄦ潵澶勭悊realm鐨勮璇併?<BR>create table users (<BR>  user_name         varchar(15) not null primary key,<BR>  user_pass         varchar(15) not null<BR>);</P> <P>create table user_roles (<BR>  user_name         varchar(15) not null,<BR>  role_name         varchar(15) not null,<BR>  primary key (user_name, role_name)<BR>); <BR> </P> <P><BR>JDBC椹卞姩 </P> <P>浣犻渶瑕佸皢浣犵殑JDBC鍚姩鍖呮斁鍦?$CATALINA_HOME/server/lib 鐩綍鎴栬?$CATALINA_HOME/common/lib 鐩綍涓嬶紝紜繚Tomcat鑳介氳繃CLASSPATH鎵懼埌瀹冦備嬌鐢╩ysql鏁版嵁搴撶殑璇濓紝浣犲彲浠ヤ嬌鐢ㄧ被浼?mm.mysql-2.0.4-bin.jar 鐨勯┍鍔ㄥ寘錛汷racle 9i浣犲彲浠ヤ嬌鐢╫jdbc14.jar絳塐racle鑷甫鐨勯┍鍔紱PostgreSQL鍙互鍦?A >http://jdbc.postgresql.org/</A> 鍙栧緱鍚堥傜殑椹卞姩紼嬪簭銆?</P> <P>緙栬緫server.xml </P> <P>緙栬緫$CATALINA_HOME/conf/server.xml鏂囦歡錛屽湪host閲屾坊鍔犲涓嬬墖孌碉紙浠ySQL涓轟緥錛?<BR> <Realm className = 'org.apache.catalina.realm.JDBCRealm' debug='0'<BR>      driverName = 'org.gjt.mm.mysql.Driver'<BR>connectionURL = 'jdbc:mysql://localhost/authority?user=dbuser&password=dbpass'<BR>       userTable='users' userNameCol='user_name' userCredCol='user_pass'<BR>   userRoleTable='user_roles' roleNameCol='role_name'/></P> <P> </P> <P><BR>鍏朵腑 jdbc:mysql://localhost/authority?user=dbuser&password=dbpass 鏄疢ysql鐨勮繛鎺ヤ覆錛屼綘鍙互鏍規(guī)嵁浣犵殑闇瑕佽繘琛屼慨鏀廣傚叾鏈夊叧灞炴т粙緇嶅涓嬶細(xì) 灞炴?鎻忚堪 <BR>className Realm鐨勫疄鐜扮被錛岃繖閲屽繀欏繪槸 'org.apache.catalina.realm.JDBCRealm' <BR> <BR>connectionName 鏁版嵁搴撶敤鎴峰悕<BR> <BR>connectionPassword 鏁版嵁搴撶敤鎴風(fēng)殑瀵嗙爜<BR> <BR>connectionURL 鏁版嵁搴撶殑JDBC榪炴帴涓?BR> <BR>debug Debug鐨勭▼搴︼紝瀹冨拰Logger鐩稿叧閰嶇疆閰嶅悎浣跨敤錛屽艱秺楂樹(shù)俊鎭秺璇︾粏錛岀己鐪佷負(fù)0<BR> <BR>digest 瀛樺偍瀵嗙爜鐨勫姞瀵嗘柟寮忥紝濡傛灉涓嶆寚瀹氬垯鏄槑鏂囧瓨鍌ㄣ傛寚瀹氫負(fù) java.security.MessageDigest 涔嬬被鐨勭被鍚嶅垯瑕佺湅鏁版嵁搴撻噷琛ㄤ腑鐢ㄦ埛瀵嗙爜鐨勫瓨鏀炬牸寮忋?<BR> <BR>driverName 鏁版嵁搴撻┍鍔ㄧ▼搴忕被<BR> <BR>roleNameCol 瑙掕壊琛ㄧ殑瀛樻斁瑙掕壊鍚嶇殑瀛楁鍚?<BR> <BR>userCredCol 鐢ㄦ埛琛ㄩ噷瀛樻斁瀵嗙爜鐨勫瓧孌靛悕<BR> <BR>userNameCol 鐢ㄦ埛琛ㄤ腑瀛樻斁鐢ㄦ埛鍚嶇殑瀛楁鍚?BR> <BR>userRoleTable 瑙掕壊琛ㄧ殑琛ㄥ悕錛堢被浼?etc/group錛?BR> <BR>userTable 鐢ㄦ埛琛ㄧ殑琛ㄥ悕<BR> </P> <P><BR>娉ㄦ剰鐐?</P> <P>濡傛灉浣犲鐢ㄦ埛琛ㄨ繘琛屼簡(jiǎn)鏂板鎿嶄綔鍜屼慨鏀規(guī)搷浣滐紝閭d箞浼?xì)瀹炴椂浣滅敤浜庢瑕仒q涜鐧婚檰鎿嶄綔鐨勭敤鎴鳳紱 <BR>鐢ㄦ埛宸茬粡瀹屾垚鐧婚檰鍚庯紝浣犲瀹冭繘琛岀殑鍒犻櫎淇敼鎿嶄綔錛屽茍涓嶈兘瀹炴椂浣滅敤浜庣敤鎴風(fēng)殑褰撳墠鐘舵侊紝鍙兘鍦ㄦ鐢ㄦ埛涓嬫鐧婚檰鐨勬椂鍊欑敓鏁堬紱錛堝鏋滄槸鍩轟簬琛ㄥ崟璁よ瘉鐨勭敤鎴鳳紝鏄湪浼?xì)璇澗l撴潫鎴栬呬粬娉ㄩ攢鍚庡綋鍓嶈璇佸け鏁堬紱濡傛灉鏄熀紜璁よ瘉鐨勭敤鎴峰垯闇瑕佺瓑鍒板綋鍓嶇獥鍙e叧闂級(jí) <BR>瀵規(guī)暟鎹簱閲岄偅涓や釜琛ㄧ殑澧炲垹鏀圭鐞嗭紝浣犻渶瑕佽嚜琛岀紪鍐欏悎閫傜殑涓氬姟浠g爜錛孴omcat騫舵病鏈夋彁渚涙爣鍑嗙殑瀹炵幇錛岃繖鏄病鏈夋剰涔夌殑銆?<BR>緙栬瘧鑰呮敞錛氳繖閮ㄥ垎鍐呭鏄府鍔﹏ewbie鐞嗚ВRealm鑰岀洿鎺ヤ粠Realm Configuration HOW-TO涓憳璇戠殑錛屾槸鎴戜滑瀹屾暣渚嬪瓙鎵蹇呴』瑕佷簡(jiǎn)瑙e茍姝g‘閰嶇疆鐨勯儴鍒嗭紝涓嶈繃浼間箮娌℃湁鐪嬪埌綾諱技鐨勮瘧鏂囷紝灝卞仛浜?jiǎn)杩欎欢绡忚禈鐨勪簨鎯呫傝繖緋誨垪鏂囩珷瀵圭啛鎵嬪熀鏈病鏈変粈涔堝府鍔╋紝璇瘋璋呫?</P> <P> </P><img src ="http://www.tkk7.com/lmsun/aggbug/10300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-17 09:41 <a href="http://www.tkk7.com/lmsun/articles/10300.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>tomcat5.0+mysql閰嶇疆JDBCRealm,DBCP,ssl,鍙?qiáng)涓枃湄曠爜瑙e唽櫙﹁?/title><link>http://www.tkk7.com/lmsun/articles/10299.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Wed, 17 Aug 2005 01:38:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10299.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10299.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10299.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10299.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10299.html</trackback:ping><description><![CDATA[<P>鍑嗗鐜:<BR>1.j2sdk-1_4_2-windows-i586.exe    //jdk<BR>2.mysql-4.0.20d-win.zip        //mysql鏁版嵁搴?BR>3.mysqlcc-0.9.4-win32.zip    //mysqlGUI鎺у埗<BR>4.jakarta-tomcat-5.0.27.exe    //tomcat鏈嶅姟鍣?BR>5.mysql-connector-java-3.0.14-production.zip //鍐呭惈mysql椹卞姩</P> <P>瀹夎姝ラ:<BR>1.瀹夎jdk<BR>2.瀹夎tomcat<BR>3.瀹夎mysql<BR>4.瀹夎mysqlcc<BR>5.灝嗛┍鍔ㄥ寘瑙e帇,鎷瘋礉mysql-connector-java-3.0.14-production-bin.jar鍒皌omcat/common/lib涓?BR>鎴栬呬笅杞絤m.mysql-2.0.14-you-must-unjar-me.jar,瑙e帇鍚庢嫹璐濆叾涓殑mm.mysql-2.0.14-bin.jar</P> <P>Tomcat5.0閰嶇疆 鏈緥浣跨敤瀹夎瀵嗙爜 198277<BR>1.閰嶇疆manager 綆$悊搴旂敤紼嬪簭<BR>鍦╟onf/server.xml 涓?BR>娣誨姞濡備笅</P> <P><Service name="Catalina"><BR>...</P> <P>    <Context path="/manager" debug="0" privileged="true"<BR>             docBase="/usr/local/kinetic/tomcat5/server/webapps/manager"><BR>    </Context></P> <P></Service> </P> <P>闄愬埗ip璁塊棶閰嶇疆<BR><Context path="/manager" debug="0" privileged="true"<BR>         docBase="/usr/local/kinetic/tomcat5/server/webapps/manager"><BR>         <Valve className="org.apache.catalina.valves.RemoteAddrValve"<BR>                allow="127.0.0.1"/><BR></Context><BR>嫻嬭瘯涓?http://localhost:8080/manager/html</P> <P>2.閰嶇疆JDBCRealm瀹瑰櫒綆$悊瀹夊叏,浠ysql-4.0鏁版嵁搴撲負(fù)渚?BR>a.鎷瘋礉椹卞姩mm.mysql-2.0.14-bin.jar鍒癱ommon/lib/涓?BR>b.鍦ㄦ暟鎹簱ycg涓緩琛?BR>   <BR> create table users (<BR>  user_name         varchar(15) not null primary key,<BR>  user_pass         varchar(15) not null<BR>);</P> <P>create table user_roles (<BR>  user_name         varchar(15) not null,<BR>  role_name         varchar(15) not null,<BR>  primary key (user_name, role_name)<BR>);</P> <P>c.淇敼server.xml濡備笅(榛樿鏁版嵁搴撲負(fù)root,鏃犲瘑鐮?濡傛灉鏈夊艦濡?connectionURL="jdbc:mysql://localhost/authority?</P> <P>user=dbuser&password=dbpass")<BR>      <Realm  className="org.apache.catalina.realm.JDBCRealm" debug="99"<BR>             driverName="org.gjt.mm.mysql.Driver"<BR>          connectionURL="jdbc:mysql://localhost/ycg?user=root"<BR>         connectionName="" connectionPassword=""<BR>              userTable="users" userNameCol="user_name" userCredCol="user_pass"<BR>          userRoleTable="user_roles" roleNameCol="role_name" /></P> <P>d.鍦ㄦ暟鎹簱涓坊鍔犲叆tomcat鐨勯粯璁ら厤緗暟鎹?</P> <P>+-----------+-----------+<BR>| user_name | role_name |<BR>+-----------+-----------+<BR>| admin     | admin     |<BR>| admin     | manager   |<BR>| both      | role1     |<BR>| both      | tomcat    |<BR>| role1     | role1     |<BR>| tomcat    | tomcat    |<BR>+-----------+-----------+<BR>+-----------+-----------+<BR>| user_name | user_pass |<BR>+-----------+-----------+<BR>| tomcat    | tomcat    |<BR>| both      | tomcat    |<BR>| role1     | tomcat    |<BR>| admin     | 198277    |<BR>+-----------+-----------+</P> <P>e.鍚姩mysql,鍚姩tomcat,姝ゅ悗tomcat灝嗕粠鏁版嵁搴撲腑璇葷敤鎴瘋鍒欒璇?榛樿鐨刢onf/tomcat-users.xml澶辨晥</P> <P>3.DBCP鐨勯厤緗?BR>a.璁劇疆<BR>             <parameter><BR>              <name>removeAbandoned</name><BR>              <value>true</value><BR>            </parameter></P> <P> 鍙嬌澶辨晥鐨勬暟鎹繛鎺ラ噸鏂板惎鐢?<BR>閰嶅璁劇疆<BR>   <BR>             <parameter><BR>              <name>removeAbandonedTimeout</name><BR>              <value>60</value><BR>            </parameter><BR>澶辨晥鏃墮棿<BR>濡傛灉瑕佸啓鍏ユ棩蹇?BR>璁劇疆<BR>            <parameter><BR>              <name>logAbandoned</name><BR>              <value>true</value><BR>            </parameter><BR>浠ヤ笂涓変釜榛樿閮芥槸false<BR>b.浠ysql涓轟緥,閰嶇疆鏁版嵁榪炴帴姹?BR>c.閰嶇疆鏂扮殑鐢ㄦ埛涓庢暟鎹簱,蹇呴』璁懼畾瀵嗙爜,絀哄瘑鐮佸皢瀵艱嚧榪炴帴澶辮觸<BR>e.<BR>鎸囧畾root瀵嗙爜:mysqladmin -u root -h localhost password "198277"<BR>(闇淇敼涓婇潰鐨刯dbcrealm璁劇疆connectionURL="jdbc:mysql://localhost/ycg?user=root&password=198277")<BR>鍛戒護(hù)mysql榪涘叆鍖垮悕榪炴帴鍒版湇鍔″櫒<BR>瀵嗙爜璁塊棶<BR>shell> mysql -h host -u user -p<BR>Enter password: ********</P> <P>//濡傛灉root娌℃湁瀵嗙爜,浠ヤ笅鏄笉鎴愬姛鐨?(璇曡繃浜?<BR> mysql> GRANT ALL PRIVILEGES ON *.* TO <A href="mailto:javauser@localhost">javauser@localhost</A> <BR>    ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION;<BR>mysql> create database javatest;<BR>mysql> use javatest;<BR>mysql> create table testdata (<BR>    ->   id int not null auto_increment primary key,<BR>    ->   foo varchar(25), <BR>    ->   bar int);</P> <P>鍦╟onf/server.xml涓?lt;host></host>涓坊鍔?BR><Context path="/DBTest" docBase="DBTest"<BR>        debug="5" reloadable="true" crossContext="true"></P> <P>  <Logger className="org.apache.catalina.logger.FileLogger"<BR>             prefix="localhost_DBTest_log." suffix=".txt"<BR>             timestamp="true"/></P> <P>  <Resource name="jdbc/TestDB"<BR>               auth="Container"<BR>               type="javax.sql.DataSource"/></P> <P>  <ResourceParams name="jdbc/TestDB"><BR>    <parameter><BR>      <name>factory</name><BR>      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value><BR>    </parameter></P> <P>    <!-- Maximum number of dB connections in pool. Make sure you<BR>         configure your mysqld max_connections large enough to handle<BR>         all of your db connections. Set to 0 for no limit.<BR>         --><BR>    <parameter><BR>      <name>maxActive</name><BR>      <value>100</value><BR>    </parameter></P> <P>    <!-- Maximum number of idle dB connections to retain in pool.<BR>         Set to 0 for no limit.<BR>         --><BR>    <parameter><BR>      <name>maxIdle</name><BR>      <value>30</value><BR>    </parameter></P> <P>    <!-- Maximum time to wait for a dB connection to become available<BR>         in ms, in this example 10 seconds. An Exception is thrown if<BR>         this timeout is exceeded.  Set to -1 to wait indefinitely.<BR>         --><BR>    <parameter><BR>      <name>maxWait</name><BR>      <value>10000</value><BR>    </parameter></P> <P>    <!-- MySQL dB username and password for dB connections  --><BR>    <parameter><BR>     <name>username</name><BR>     <value>javauser</value><BR>    </parameter><BR>    <parameter><BR>     <name>password</name><BR>     <value>javadude</value><BR>    </parameter></P> <P>    <!-- Class name for the old mm.mysql JDBC driver - uncomment this entry and comment next<BR>         if you want to use this driver - we recommend using Connector/J though<BR>    <parameter><BR>       <name>driverClassName</name><BR>       <value>org.gjt.mm.mysql.Driver</value><BR>    </parameter><BR>     --><BR>    <BR>    <!-- Class name for the official MySQL Connector/J driver --><BR>    <parameter><BR>       <name>driverClassName</name><BR>       <value>com.mysql.jdbc.Driver</value><BR>    </parameter><BR>    <BR>    <!-- The JDBC connection url for connecting to your MySQL dB.<BR>         The autoReconnect=true argument to the url makes sure that the<BR>         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the<BR>         connection.  mysqld by default closes idle connections after 8 hours.<BR>         --><BR>    <parameter><BR>      <name>url</name><BR>      <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value><BR>    </parameter></P> <P><BR>            <parameter><BR>              <name>removeAbandoned</name><BR>              <value>true</value><BR>            </parameter></P> <P>             <parameter><BR>              <name>removeAbandonedTimeout</name><BR>              <value>60</value><BR>            </parameter><BR>            <parameter><BR>              <name>logAbandoned</name><BR>              <value>true</value><BR>            </parameter><BR>  </ResourceParams><BR></Context></P> <P>f.鍦╳eb鏈嶅姟涓皟鐢?閰嶇疆web.xml 濡?<BR><web-app xmlns="<A <BR>    xmlns:xsi="<A <BR>    xsi:schemaLocation="<A >http://java.sun.com/xml/ns/j2ee</A><BR><A <BR>    version="2.4"><BR>  <description>MySQL Test App</description><BR>  <resource-ref><BR>      <description>DB Connection</description><BR>      <res-ref-name>jdbc/TestDB</res-ref-name><BR>      <res-type>javax.sql.DataSource</res-type><BR>      <res-auth>Container</res-auth><BR>  </resource-ref><BR></web-app><BR>g.嫻嬭瘯鐢╰est.jsp <BR><%@ taglib uri="<A prefix="sql" %><BR><%@ taglib uri="<A prefix="c" %></P> <P><sql:query var="rs" dataSource="jdbc/TestDB"><BR>select id, foo, bar from testdata<BR></sql:query></P> <P><html><BR>  <head><BR>    <title>DB Test</title><BR>  </head><BR>  <body></P> <P>  <h2>Results</h2><BR>  <BR><c:forEach var="row" items="${rs.rows}"><BR>    Foo ${row.foo}<br/><BR>    Bar ${row.bar}<br/><BR></c:forEach></P> <P>  </body><BR></html></P> <P>h.鏂板緩web搴旂敤<BR>涓嬭澆jakarta-taglibs-standard-1.1.0<BR>copy jstl.jar and standard.jar to your web app's WEB-INF/lib </P> <P>DBTest/<BR>    WEB-INF/<BR>        web.xml<BR>        lib/<BR>            jstl.jar<BR>            standard.jar<BR>    test.jsp<BR>鎷瘋礉鍒皐ebapps/ 涓?BR>i.鍚姩mysql,tomcat <BR>璁塊棶:<BR><A href="http://localhost:8080/DBTest/test.jsp">http://localhost:8080/DBTest/test.jsp</A><BR>鏄劇ず:<BR>    Results<BR>    Foo hello<BR>    Bar 12345</P> <P>4.ssl鐨勯厤緗?浠dk1.4.2涓轟緥<BR>a.榪涘叆%JAVA_HOME%\bin<BR>榪愯鍛戒護(hù):keytool -genkey -alias tomcat -keyalg RSA<BR>浠omcat 瀹夎瀵嗙爜涓?98277,ketool璁劇疆瀵嗙爜涓?98277涓轟緥<BR>杈撳叆keystore瀵嗙爜錛?nbsp; 198277<BR>鎮(zhèn)ㄧ殑鍚嶅瓧涓庡姘忔槸浠涔堬紵<BR>  [Unknown]錛?nbsp; ycg<BR>鎮(zhèn)ㄧ殑緇勭粐鍗曚綅鍚嶇О鏄粈涔堬紵<BR>  [Unknown]錛?nbsp; nju<BR>鎮(zhèn)ㄧ殑緇勭粐鍚嶇О鏄粈涔堬紵<BR>  [Unknown]錛?nbsp; nju<BR>鎮(zhèn)ㄦ墍鍦ㄧ殑鍩庡競(jìng)鎴栧尯鍩熷悕縐版槸浠涔堬紵<BR>  [Unknown]錛?nbsp; nanjing<BR>鎮(zhèn)ㄦ墍鍦ㄧ殑宸炴垨鐪佷喚鍚嶇О鏄粈涔堬紵<BR>  [Unknown]錛?nbsp; jiangsu<BR>璇ュ崟浣嶇殑涓ゅ瓧姣嶅浗瀹朵唬鐮佹槸浠涔?BR>  [Unknown]錛?nbsp; nd<BR>CN=ycg, OU=nju, O=nju, L=nanjing, ST=jiangsu, C=nd 姝g‘鍚楋紵<BR>  [鍚錛?nbsp; y</P> <P>杈撳叆<tomcat>鐨勪富瀵嗙爜<BR>        錛堝鏋滃拰 keystore 瀵嗙爜鐩稿悓錛屾寜鍥炶濺錛夛細(xì)  198277<BR>b.鍦ㄤ綘鐨凞:\Documents and Settings\鐨勫綋鍓嶇敤鎴風(fēng)洰褰曚笅鍙互鎵懼埌.keystore鏂囦歡.灝嗗叾鎷瘋礉鍒癱onf/鏂囦歡澶逛笅.<BR>c.鍦╯erver.xml 涓壘鍒?/P> <P>    <!--<BR>    <Connector port="8443" <BR>               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<BR>               enableLookups="false" disableUploadTimeout="true"<BR>               acceptCount="100" debug="0" scheme="https" secure="true"<BR>               clientAuth="false" sslProtocol="TLS" /><BR>    --><BR>    鍘繪帀娉ㄩ噴</P> <P>娣誨姞閰嶇疆瀛楁:keystoreFile="/conf/.keystore" keystorePass="198277"<BR>濡? <!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --><BR>   <BR>    <Connector port="8443" <BR>               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<BR>               enableLookups="false" disableUploadTimeout="true"<BR>               acceptCount="100" debug="0" scheme="https" secure="true"<BR>               clientAuth="false" sslProtocol="TLS" keystoreFile="/conf/.keystore"<BR>               keystorePass="198277"/><BR>d.嫻嬭瘯涓?<BR><A href="https://localhost:8443">https://localhost:8443</A><BR>e.鍦ㄨ嚜宸辯殑紼嬪簭涓坊鍔爏sl璁よ瘉鏂瑰紡涓?<BR>鍦╳eb.xml 涓?lt;web-app></web-app>娣誨姞<BR><security-constraint><BR><web-resource-collection><BR><web-resource-name>Success</web-resource-name><BR><url-pattern>/</url-pattern><BR><http-method>GET</http-method><BR><http-method>POST</http-method><BR></web-resource-collection><BR><user-data-constraint><BR><transport-guarantee>CONFIDENTIAL</transport-guarantee><BR></user-data-constraint><BR></security-constraint><BR>f.鐢ㄤ笂鎻愪負(fù)渚嬪氨鏄?BR>淇敼web.xml 涓?BR><web-app xmlns="<A <BR>    xmlns:xsi="<A <BR>    xsi:schemaLocation="<A >http://java.sun.com/xml/ns/j2ee</A><BR><A <BR>    version="2.4"></P> <P>    <description>MySQL Test App</description></P> <P><security-constraint><BR><web-resource-collection><BR><web-resource-name>Success</web-resource-name><BR><url-pattern>/</url-pattern><BR><http-method>GET</http-method><BR><http-method>POST</http-method><BR></web-resource-collection><BR><user-data-constraint><BR><transport-guarantee>CONFIDENTIAL</transport-guarantee><BR></user-data-constraint><BR></security-constraint></P> <P>  <BR>  <resource-ref><BR>      <description>DB Connection</description><BR>      <res-ref-name>jdbc/TestDB</res-ref-name><BR>      <res-type>javax.sql.DataSource</res-type><BR>      <res-auth>Container</res-auth><BR>  </resource-ref><BR></web-app><BR>璁塊棶:<BR><A href="https://localhost:8443/DBTest/test.jsp">https://localhost:8443/DBTest/test.jsp</A></P> <P>g.濡傛灉涓?閰嶇疆鐨刯dbcRealm緇撳悎璧鋒潵榪涜琛ㄥ崟璁よ瘉<BR>鍏堝湪user_roles琛ㄤ腑娣誨姞user_name:ycg role_name:web-user<BR>鍦╱sers琛ㄤ腑娣誨姞user_name:ycg user_pass:198277</P> <P>鐒跺悗鍦╳eb.xml涓坊鍔?BR><auth-constraint><BR><role-name>web-user</role-name><BR></auth-constraint></P> <P><login-config><BR> <auth-method>BASIC</auth-method><BR> <realm-name>My Member Area</realm-name><BR></login-config></P> <P>淇敼鍚庣殑web.xml濡?<BR><web-app xmlns="<A <BR>    xmlns:xsi="<A <BR>    xsi:schemaLocation="<A >http://java.sun.com/xml/ns/j2ee</A><BR><A <BR>    version="2.4"></P> <P>    <description>MySQL Test App</description></P> <P><security-constraint><BR><web-resource-collection><BR><web-resource-name>Success</web-resource-name><BR><url-pattern>/</url-pattern><BR><http-method>GET</http-method><BR><http-method>POST</http-method><BR></web-resource-collection><BR><auth-constraint><BR><role-name>web-user</role-name><BR></auth-constraint><BR><user-data-constraint><BR><transport-guarantee>CONFIDENTIAL</transport-guarantee><BR></user-data-constraint><BR></security-constraint><BR><login-config><BR> <auth-method>BASIC</auth-method><BR> <realm-name>My Member Area</realm-name><BR></login-config><BR>  <BR>  <resource-ref><BR>      <description>DB Connection</description><BR>      <res-ref-name>jdbc/TestDB</res-ref-name><BR>      <res-type>javax.sql.DataSource</res-type><BR>      <res-auth>Container</res-auth><BR>  </resource-ref><BR></web-app></P> <P>嫻嬭瘯:<BR><A href="http://localhost:8080/DBTest/test.jsp">http://localhost:8080/DBTest/test.jsp</A><BR>灝嗛氳繃ssl榪炴帴,騫惰繘琛岃〃鍗曡璇?鐢ㄦ埛瀵嗙爜鍙湪user_roles,鍜寀sers涓坊鍔?</P> <P>5.涓枃涔辯爜闂:<BR>mysql 榛樿緙栫爜 iso<BR>tomcat request 浼犺緭緙栫爜 iso <BR>濡傛灉瑕佹樉紺轟腑鏂?BR>鍦?.jsp涓坊鍔?BR><head><BR><%@ page <BR>language="java"<BR>contentType="text/html; charset=GB18030"<BR>pageEncoding="GB18030"<BR>%><BR></head><BR>濡傛灉鏄暟鎹紶杈撲腑鐨勪貢鐮?濡傜敤servlet浠巑ysql鏁版嵁搴撹鍑虹殑鏁版嵁)<BR>鐢ㄤ互涓嬩袱涓漿鐮佸嚱鏁拌漿鐮?濡傛灉涓嶆竻妤氱敱鍝緙栫爜杞垚鍝緙栫爜,灝卞灝濊瘯.<BR>    //杞爜GBK杞琁SO<BR>    public String toISO(String input) {<BR>        try {<BR>                byte[] bytes = input.getBytes("GBK");<BR>                return new String(bytes,"ISO8859-1");<BR>        }catch(Exception ex) {<BR>        }<BR>        return input;</P> <P>    }<BR>    <BR>    //杞爜IS0杞珿BK<BR>    public String toGBK(String input) {<BR>        try {<BR>            byte[] bytes = input.getBytes("ISO8859-1");<BR>            return new String(bytes,"GBK");<BR>        }catch(Exception ex) {<BR>        }<BR>        return input;<BR>    }</P> <P><BR>浠ヤ笂閰嶇疆閮芥祴璇曢氳繃.涓昏鍙傝僼omcat5.0鐨勫府鍔╂枃妗?灝嗚繃紼嬪啓鍑烘潵涓庡ぇ瀹跺叡浜?濡傛灉鍙戠幇鍏朵腑閿欒,璇鋒寚鍑?<BR>嬈㈣繋緇欐垜鏉ヤ俊<A href="mailto:ycg01@software.nju.edu.cn">ycg01@software.nju.edu.cn</A>鍏卞悓鎺㈣. </P><img src ="http://www.tkk7.com/lmsun/aggbug/10299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-17 09:38 <a href="http://www.tkk7.com/lmsun/articles/10299.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>感谢您访问我们的网站,您可能还对以下资源感兴趣:</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> 主站蜘蛛池模板: <a href="http://fenxiangceo.com" target="_blank">福利免费在线观看</a>| <a href="http://louqibang.com" target="_blank">永久看日本大片免费35分钟 </a>| <a href="http://junyehome.com" target="_blank">日韩免费的视频在线观看香蕉</a>| <a href="http://okbala.com" target="_blank">国产1024精品视频专区免费</a>| <a href="http://jxszzhzs.com" target="_blank">亚洲精品无码永久在线观看</a>| <a href="http://meiluniao.com" target="_blank">亚洲AV成人片色在线观看高潮</a>| <a href="http://wwwav800.com" target="_blank">亚洲AV成人一区二区三区在线看</a>| <a href="http://www6661126.com" target="_blank">乱爱性全过程免费视频</a>| <a href="http://783944.com" target="_blank">最近最好最新2019中文字幕免费</a>| <a href="http://888-28.com" target="_blank">免费a级毛片大学生免费观看</a>| <a href="http://hzsprfm.com" target="_blank">亚洲综合免费视频</a>| <a href="http://yaboxxx125.com" target="_blank">又硬又粗又长又爽免费看 </a>| <a href="http://xianfeng-motor.com" target="_blank">亚洲国产成人精品无码区在线网站</a>| <a href="http://milbolg.com" target="_blank">人人公开免费超级碰碰碰视频</a>| <a href="http://thegaybdsm.com" target="_blank">亚洲成?v人片天堂网无码</a>| <a href="http://xuanzhicity.com" target="_blank">亚洲日本va在线观看</a>| <a href="http://lwjiheng.com" target="_blank">野花香在线视频免费观看大全</a>| <a href="http://qihongxia.com" target="_blank">免费鲁丝片一级在线观看</a>| <a href="http://5gg1.com" target="_blank">久久久久亚洲av无码专区</a>| <a href="http://zzo8.com" target="_blank">中文字幕一区二区三区免费视频</a>| <a href="http://aplus178.com" target="_blank">亚洲午夜未满十八勿入网站2</a>| <a href="http://51ykz.com" target="_blank">美女视频黄a视频全免费网站一区</a>| <a href="http://0595laser.com" target="_blank">最近中文字幕免费完整</a>| <a href="http://aqd1987.com" target="_blank">亚洲日本香蕉视频观看视频</a>| <a href="http://zzjiji.com" target="_blank">永久免费av无码入口国语片</a>| <a href="http://99rlcf.com" target="_blank">亚洲国产婷婷香蕉久久久久久 </a>| <a href="http://shaonvfushi.com" target="_blank">国内精品免费麻豆网站91麻豆</a>| <a href="http://1992zyzp.com" target="_blank">亚洲色成人WWW永久网站</a>| <a href="http://55xxb.com" target="_blank">黄网站免费在线观看</a>| <a href="http://chuguo65.com" target="_blank">久久av无码专区亚洲av桃花岛</a>| <a href="http://zzhdrsqwx.com" target="_blank">日本片免费观看一区二区</a>| <a href="http://www50884.com" target="_blank">亚洲天堂中文资源</a>| <a href="http://yeyaweiban.com" target="_blank">中文字幕免费在线看线人动作大片</a>| <a href="http://haiholr.com" target="_blank">久久被窝电影亚洲爽爽爽 </a>| <a href="http://zzz134.com" target="_blank">最新国产精品亚洲</a>| <a href="http://km9c.com" target="_blank">国产精品免费视频一区</a>| <a href="http://xxxxcccc.com" target="_blank">亚洲日韩AV无码一区二区三区人 </a>| <a href="http://qiseka.com" target="_blank">自拍偷自拍亚洲精品被多人伦好爽</a>| <a href="http://s4lm0x.com" target="_blank">亚洲av午夜国产精品无码中文字</a>| <a href="http://zjtuntex.com" target="_blank">18禁黄网站禁片免费观看不卡</a>| <a href="http://8v4y.com" target="_blank">亚洲色欲色欲www</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>