首页 > 解决方案 > 尝试使用 Spring 和 JavaMailSender 发送带附件的邮件,但显示“找不到”(403)和“拒绝访问”,但提供了访问权限

问题描述

向具有员工访问权限的用户发送邮件网页时访问被拒绝。它给出了 403 错误并拒绝访问,但是对于员工角色,我提供了对以“/”开头的网页的访问权限,而不是“/leaders”或“/admin”。

DemoConfig 文件是 -

    package com.akshay.www.config;

import java.beans.PropertyVetoException;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration
@ComponentScan("com.akshay.www")
@EnableWebMvc
@EnableTransactionManagement
public class DemoConfig {

    @Bean
    public ViewResolver vs()
    {
        InternalResourceViewResolver vs= new InternalResourceViewResolver();
        vs.setPrefix("/WEB-INF/view/");
        vs.setSuffix(".jsp");
        return vs;
    }
    @Bean
    public DataSource ds()
    {
        ComboPooledDataSource cs= new ComboPooledDataSource();
        try {
            cs.setDriverClass("com.mysql.jdbc.Driver");
        } catch (PropertyVetoException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        cs.setJdbcUrl("jdbc:mysql://localhost:3306/employeemanagement?useSSL=false&serverTimezone=UTC");
        cs.setUser("root");
        cs.setPassword("");
        cs.setMaxIdleTime(30000);
        cs.setMinPoolSize(5);
        cs.setMaxPoolSize(20);
        cs.setInitialPoolSize(5);
        return cs;
    }
    
    public Properties props()
    {
        Properties p= new Properties();
        p.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        p.setProperty("hibernate.show_sql", "true");
        return p;
    }
    
    @Bean
    public LocalSessionFactoryBean sessionFactory()
    {
        LocalSessionFactoryBean sessionFactory= new LocalSessionFactoryBean();
        sessionFactory.setHibernateProperties(props());
        sessionFactory.setPackagesToScan("com.akshay.www");
        sessionFactory.setDataSource(ds());
        return sessionFactory;
    }
    
    @Bean
    @Autowired
    public HibernateTransactionManager thc(SessionFactory sessionFactory)
    {
        HibernateTransactionManager htx= new HibernateTransactionManager();
        htx.setSessionFactory(sessionFactory);
        return htx;
    }
    
    @Bean
    public JavaMailSenderImpl javaMailSenderImpl()
    {
        JavaMailSenderImpl js= new JavaMailSenderImpl();
        js.setHost("smtp.gmail.com");
        js.setPort(587);
        js.setUsername("*************");
        js.setPassword("**********");
        Properties p = new Properties();
        p.setProperty("mail.smtp.auth", "true");
        p.setProperty("mail.smtp.starttls.enable", "true");
        //p.setProperty("mail.transport.protocol", "smtp");
        js.setProtocol("smtp");
        js.setJavaMailProperties(p);
        return js;
    }
    
    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
       // multipartResolver.setMaxUploadSize(100000);
        return multipartResolver;
    }
}

ServletDispatcher——

package com.akshay.www.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletDispatcher extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return new Class<?>[] {DemoConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String[] {"/"};
    }

}

Spring 安全配置——

package com.akshay.www.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.akshay.www.service.UserLayer;
@Configuration
@EnableWebSecurity
public class DemoSecurity extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserLayer myUserLayerimp;
    
    @Autowired
    private CustomSuccessHandler customSuccessHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // TODO Auto-generated method stub
        
        auth.authenticationProvider(authenticationprovider());
    }
    @Bean
    public DaoAuthenticationProvider authenticationprovider() {
        // TODO Auto-generated method stub
        DaoAuthenticationProvider ds= new DaoAuthenticationProvider();
        ds.setPasswordEncoder(bcrypt());
        ds.setUserDetailsService(myUserLayerimp);
        
        return ds;
    }
    @Bean
    public BCryptPasswordEncoder bcrypt() {
        // TODO Auto-generated method stub
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // TODO Auto-generated method stub
    
        http.authorizeRequests().antMatchers("/").hasRole("EMPLOYEE").antMatchers("/leaders/**").hasRole("MANAGER")
        .antMatchers("/admin/**").hasRole("ADMIN").and().formLogin().loginPage("/showlogin")
        .loginProcessingUrl("/authenticateTheUser").successHandler(customSuccessHandler).permitAll()
        .and().logout().permitAll().and().exceptionHandling().accessDeniedPage("/access-denied");
        
    }
    
    
    
    
}

CustomSuccessHandler---

package com.akshay.www.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.akshay.www.entity.User;
import com.akshay.www.service.UserLayer;
@Component
public class CustomSuccessHandler implements AuthenticationSuccessHandler {

    
    @Autowired
    private UserLayer myUserLayerimp;
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        // TODO Auto-generated method stub
        String theuser= authentication.getName();
        User user= myUserLayerimp.getuserbyname(theuser);
        HttpSession s= request.getSession();
        s.setAttribute("user",user);
        response.sendRedirect(request.getContextPath()+"/");

    }

}

用户界面 -

package com.akshay.www.service;

import org.springframework.security.core.userdetails.UserDetailsService;

import com.akshay.www.entity.CRM;
import com.akshay.www.entity.Email;
import com.akshay.www.entity.User;

public interface UserLayer extends UserDetailsService {

    User getuserbyname(String theuser);

    void savethisuser( CRM crmuser);

    void sendemail(Email m);

    void sendemail();

    void sendemailwithattachment(Email m, String path);

}

UserPrincipal 类-

package com.akshay.www.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.akshay.www.entity.User;

public class UserPrincipal implements UserDetails {
    private User user;

    
    public UserPrincipal(User user) {
        super();
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        List<GrantedAuthority> lis= new ArrayList<>();
        this.user.getRole().forEach(roles->
        {
                GrantedAuthority gs= new SimpleGrantedAuthority(roles.getRole_name());
                lis.add(gs);
        });
        return lis;
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return this.user.getPassword();
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return this.user.getUserName();
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }

}

控制器 -

package com.akshay.www.controller;

import java.io.FileOutputStream;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.akshay.www.entity.CRM;
import com.akshay.www.entity.Email;
import com.akshay.www.entity.User;
import com.akshay.www.service.UserLayer;

@Controller
public class DemoController {
    
    @Autowired
    private UserLayer myUserLayerimp;

    @GetMapping("/")
    public String home()
    {
        
        return "home";
    }
    
    @GetMapping("/showlogin")
    public String showlogin()
    {
        return "fancy-login";
    }
    
    @PostMapping("/register/processRegistrationForm")
    public String registernewuser(@Valid @ModelAttribute("crmUser") CRM crmuser,BindingResult binding,Model m)
    {
        if(binding.hasErrors())
        {
            return "registration-form";
        }
        User user = myUserLayerimp.getuserbyname(crmuser.userName);
        if(user!=null  || !(crmuser.password.equals(crmuser.password2)))
        {m.addAttribute("crmUser",new CRM());
        m.addAttribute("registrationError","UserName already exists or your both password doesnt match.");
            return "registration-form";
        }
        
        myUserLayerimp.savethisuser(crmuser);
        return "fancy-login";
    }
    
    @GetMapping("/register/showRegistrationForm")
    public String registernewuser(Model m)
    {m.addAttribute("crmUser",new CRM());
        return "registration-form";
    }
    
    
    @GetMapping("/leaders")
    public String registernssewuser()
    {
        return "leaders";
    }
    @GetMapping("/admins")
    public String registernsssdsewuser()
    {
        return "admin";
    }
    
    
    @GetMapping("/sendemail")
    public String sendemail(Model m)
    {
        m.addAttribute("email",new Email());
        return "emailtemp";
        
    }
    @GetMapping("/sendemailwithattachment")
    public String sendemailwithattachment(Model m)
    {
        m.addAttribute("email",new Email());
        return "emailtempwithattachment";
        
    }
    
    @PostMapping("/sending")
    public String sending(@ModelAttribute("email") Email m,@RequestParam("body") String body)
    {   m.setBody(body);
        myUserLayerimp.sendemail(m);
        return "sent";
    }
    
    @RequestMapping("/search")
    public String hi()
    {
        return "redirect:https://www.google.com/";
    }
    
    
    @PostMapping("/sendingemail")
    public String sendingemail(@ModelAttribute("email") Email m,@RequestParam("body") String body
            ,@RequestParam("uploaded") CommonsMultipartFile file,HttpSession s)
    {   m.setBody(body);
        System.out.println(file.getContentType());
        System.out.println(file.getName());
        System.out.println(file.getOriginalFilename());
        System.out.println(file.getSize());
        System.out.println(file.getStorageDescription());
    
        byte[] data= file.getBytes();
        String path= s.getServletContext().getRealPath("/")+file.getOriginalFilename();
        FileOutputStream fs;
        try {
            fs = new FileOutputStream(path);
            fs.write(data);
            fs.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        myUserLayerimp.sendemailwithattachment(m,path);
        return "sent";
    }
    
    
    @RequestMapping("/access-denied")
    public String denied()
    {
        return "access-denied";
    }
    
}

服务层——

package com.akshay.www.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.akshay.www.dao.RoleDao;
import com.akshay.www.dao.UserDao;
import com.akshay.www.entity.CRM;
import com.akshay.www.entity.Email;
import com.akshay.www.entity.Role;
import com.akshay.www.entity.User;

@Service
public class MyUserLayerImp implements UserLayer {
    
    @Autowired
    private UserDao userdaoimp;
    
    @Autowired
    private RoleDao roledaoimp;
    
    @Autowired
    private BCryptPasswordEncoder encoder;
    
    @Autowired
    private JavaMailSender javaMailSenderImpl;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        User user = userdaoimp.getuserbyname(username);
        if (user == null) {
            throw new UsernameNotFoundException("Invalid username or password.");
        }
        UserPrincipal theuser = new UserPrincipal(user);
        return theuser;
    }

    @Override
    @Transactional
    public User getuserbyname(String theuser) {
        // TODO Auto-generated method stub
        return userdaoimp.getuserbyname(theuser);
    }

    @Override
    @Transactional
    public void savethisuser(CRM crmuser) {
        // TODO Auto-generated method stub
        User user= new User();
        user.setEmail(crmuser.email);
        user.setFirstName(crmuser.firstName);
        user.setLastName(crmuser.lastName);
        user.setPassword(encoder.encode(crmuser.password));
        user.setUsername(crmuser.userName);
        String[] lis= new String[3];
        lis= crmuser.getRoles();
        List<Role> setmyroles= new ArrayList<>(); 
        for( String l:lis)
        {
            Role r=roledaoimp.getrolebyname("ROLE_"+l);
            setmyroles.add(r);
        }
        user.setRole(setmyroles);
        userdaoimp.savethisuser(user);

    }

    @Override
    public void sendemail() {
        // TODO Auto-generated method stub
        SimpleMailMessage smp= new SimpleMailMessage();
        smp.setTo("****");
        smp.setCc("****");
        smp.setFrom("****");
        smp.setSubject("***");
        smp.setText("***");
        javaMailSenderImpl.send(smp);
        
        
        
        MimeMessage mm= javaMailSenderImpl.createMimeMessage();
        try {
            MimeMessageHelper mms= new MimeMessageHelper(mm,true);
            mms.setCc("***");
            mms.setTo("***");
            mms.setText("***");
            mms.setSubject("***");
            FileSystemResource ff= new FileSystemResource(new File("C:\\Users\\Akshay\\Desktop\\laughing-laugh.gif"));
            mms.addAttachment(ff.getFilename(), ff);
            javaMailSenderImpl.send(mm);
            
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        
        

        
    }

    @Override
    public void sendemail(Email m) {
        // TODO Auto-generated method stub
        SimpleMailMessage smp= new SimpleMailMessage();
        smp.setFrom("***");
        
        if(m.sendto.contains(","))
        {
            String[] sendto=m.getSendto().split(",");
            System.out.println(sendto);
            smp.setTo(sendto);
        }
        else if (m.sendto.length()>0)
        {
            smp.setTo(m.sendto);
        }
        if(m.cc.contains(","))
        {
            String[] cc=m.getCc().split(",");
            System.out.println(cc);
            smp.setCc(cc);
        }
        else if (m.cc.length()>0)
        {
            smp.setCc(m.cc);
        }
        if(m.bcc.contains(","))
        {
            String[] bcc=m.getBcc().split(",");
            System.out.println(bcc);
            smp.setBcc(bcc);
        }
        else if(m.bcc.length()>0)
        {
            smp.setBcc(m.bcc);
        }
        smp.setSubject(m.getSubject());
        smp.setText(m.getBody());
        javaMailSenderImpl.send(smp);
        
        
    }



@Override
    public void sendemailwithattachment(Email m, String path) {
        // TODO Auto-generated method stub
        MimeMessage mm= javaMailSenderImpl.createMimeMessage();
        try{
            MimeMessageHelper smp= new MimeMessageHelper(mm,true);
        
        smp.setFrom("***");
        
        if(m.sendto.contains(","))
        {
            String[] sendto=m.getSendto().split(",");
            System.out.println(sendto);
            smp.setTo(m.sendto);
        }
        else if (m.sendto.length()>0)
        {
            smp.setTo(m.sendto);
        }
        if(m.cc.contains(","))
        {
            String[] cc=m.getCc().split(",");
            System.out.println(cc);
            smp.setCc(cc);
        }
        else if (m.cc.length()>0)
        {
            smp.setCc(m.cc);
        }
        if(m.bcc.contains(","))
        {
            String[] bcc=m.getBcc().split(",");
            System.out.println(bcc);
            smp.setBcc(bcc);
        }
        else if(m.bcc.length()>0)
        {
            smp.setBcc(m.bcc);
        }
        smp.setSubject(m.getSubject());
        smp.setText(m.getBody());
        FileSystemResource ff= new FileSystemResource(new File(path));
        smp.addAttachment(ff.getFilename(), ff);
        javaMailSenderImpl.send(mm);
        }
        catch(MessagingException mp)
        {
            System.out.println("errors with attachment");
        }
    }

}

电子邮件类--

package com.akshay.www.entity;

public class Email {
public String sendto;
public String cc;
public String bcc;
public String subject;
public String body;
public String getSendto() {
    return sendto;
}
public void setSendto(String sendto) {
    this.sendto = sendto;
}
public String getCc() {
    return cc;
}
public void setCc(String cc) {
    this.cc = cc;
}
public String getBcc() {
    return bcc;
}
public void setBcc(String bcc) {
    this.bcc = bcc;
}
public String getSubject() {
    return subject;
}
public void setSubject(String subject) {
    this.subject = subject;
}
public String getBody() {
    return body;
}
public void setBody(String body) {
    this.body = body;
}
@Override
public String toString() {
    return "Email [sendto=" + sendto + ", cc=" + cc + ", bcc=" + bcc + ", subject=" + subject + ", body=" + body + "]";
}
public Email(String sendto, String cc, String bcc, String subject, String body) {
    super();
    this.sendto = sendto;
    this.cc = cc;
    this.bcc = bcc;
    this.subject = subject;
    this.body = body;
}
public Email() {
    super();
}


}

电子邮件模板--

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>  
    <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>  

<form:form method="post" action="${pageContext.request.contextPath }/sendingemail" modelAttribute="email" enctype="multipart/form-data">
Send To <form:input type="text" path="sendto"/><br>
Cc <form:input type="text" path="cc"/><br>
Bcc<form:input type="text" path="bcc"/><br><br>
Attachment<input type="file"  name="uploaded"/><br><br>
Subject <form:input type="text" path="subject"/><br><br>
<label >Body</label> <textarea name="body" rows="10" cols="60" ></textarea><br><br>
<button type="submit">Submit</button>


</form:form>
 

标签: springspring-mvcmodel-view-controllerspring-security

解决方案


我解决了这个问题,我将 ?${_csrf.parameterName}=${_csrf.token} 添加到表单操作的末尾

<form method="POST" action="${pageContext.request.contextPath }/sendingemail?${_csrf.parameterName}=${_csrf.token}" enctype="multipart/form-data">

它现在正在工作...

从另一个问题复制了这个


推荐阅读